package com.xbongbong.saas.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.business.rule.RuleBusinessLogger;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.constant.SizeConstant;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.elasticsearch.model.PaasEsModel;
import com.xbongbong.paas.elasticsearch.pojo.XbbAggregatedPage;
import com.xbongbong.paas.elasticsearch.util.EsUtil;
import com.xbongbong.paas.elasticsearch.util.XbbElasticsearchRestTemplate;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.enums.PaySheetTypeEnum;
import com.xbongbong.paas.enums.PlatFormEnum;
import com.xbongbong.paas.field.DefaultAttrPoJo;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.MultiUnitItemPoJo;
import com.xbongbong.paas.field.SaasParticularAttributePoJo;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.paas.help.FormDataValidateProductHelp;
import com.xbongbong.paas.help.ProSaveHelp;
import com.xbongbong.paas.log.MongoLogHelp;
import com.xbongbong.paas.log.constant.LogMemoConstant;
import com.xbongbong.paas.log.pojo.InfoArrPojo;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.pojo.AssociatedBusinessAfterSavePojo;
import com.xbongbong.paas.pojo.AttrValuePojo;
import com.xbongbong.paas.pojo.ButtonPojo;
import com.xbongbong.paas.pojo.FieldAttrEntityForImport;
import com.xbongbong.paas.pojo.WorkFlowPojo;
import com.xbongbong.paas.pojo.dto.FormDataAddDTO;
import com.xbongbong.paas.pojo.dto.FormDataListDTO;
import com.xbongbong.paas.pojo.dto.ImportFormDataDTO;
import com.xbongbong.paas.pojo.dto.SaasFormSaveDTO;
import com.xbongbong.paas.pojo.dto.ValidateDataDTO;
import com.xbongbong.paas.pojo.imports.CellTitlePojo;
import com.xbongbong.paas.pojo.imports.CellValuePojo;
import com.xbongbong.paas.pojo.imports.RowGroupPojo;
import com.xbongbong.paas.pojo.vo.FormDataAddVO;
import com.xbongbong.paas.pojo.vo.FormDataGetVO;
import com.xbongbong.paas.service.PaasFormDataService;
import com.xbongbong.paas.service.workflow.trigger.WorkflowFormDataOperationService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.helper.PageHelper;
import com.xbongbong.paas.toolbox.util.Arith;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.PageHelperUtil;
import com.xbongbong.paas.toolbox.util.RegexUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.pro.businessdata.pojo.dto.FormatExplainDTO;
import com.xbongbong.pro.businessproduct.pojo.dto.BusinessProductListDTO;
import com.xbongbong.pro.constant.BusinessConstant;
import com.xbongbong.pro.constant.ElasticConstant;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.detailtab.dto.ChangeDocumentStatusSaveDTO;
import com.xbongbong.pro.detailtab.vo.ChangeDocumentStatusSaveVO;
import com.xbongbong.pro.detailtab.vo.ProductSummaryVO;
import com.xbongbong.pro.domain.entity.ReRollBackEntity;
import com.xbongbong.pro.domain.entity.UpdateDataEntity;
import com.xbongbong.pro.enums.RefundStatusEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.BuinessDefaultErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.BusinessTypeErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.ProductErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.PurchaseErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.RefundErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.ReturnedPurchaseErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.UserTeamErrorCodeEnum;
import com.xbongbong.pro.enums.permission.enums.ProPermissionAliasEnum;
import com.xbongbong.pro.enums.workflow.TriggerEventTypeEnum;
import com.xbongbong.pro.formdata.pojo.SaasNeedRedundantAttrPojo;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainInLinkItemDTO;
import com.xbongbong.pro.listbatch.pojo.dto.AddLabelDTO;
import com.xbongbong.pro.listbatch.pojo.dto.CancelDTO;
import com.xbongbong.pro.log.pojo.dto.RuleBusinessLogDTO;
import com.xbongbong.pro.product.pojo.ProductSavePojo;
import com.xbongbong.pro.product.pojo.dto.PagingProductDTO;
import com.xbongbong.pro.product.pojo.vo.DetailProductVO;
import com.xbongbong.pro.product.pojo.vo.PagingProductVO;
import com.xbongbong.pro.purchase.pojo.dto.PurchaseUpdateBatchDTO;
import com.xbongbong.pro.purchase.pojo.dto.PurchaseUpdateDTO;
import com.xbongbong.pro.returnedpurchase.pojo.dto.ReturnedPurchaseDeleteBatchDTO;
import com.xbongbong.pro.returnedpurchase.pojo.dto.ReturnedPurchaseEditAttrUpdateDTO;
import com.xbongbong.pro.returnedpurchase.pojo.dto.ReturnedPurchaseUpdateBatchDTO;
import com.xbongbong.pro.returnedpurchase.pojo.dto.ReturnedPurchaseUpdateByBusinessRuleDTO;
import com.xbongbong.pro.returnedpurchase.pojo.dto.ReturnedPurchaseUpdateDTO;
import com.xbongbong.pro.returnedpurchase.pojo.vo.ReturnedPurchaseDeleteBatchVO;
import com.xbongbong.pro.returnedpurchase.pojo.vo.ReturnedPurchaseUpdateBatchVO;
import com.xbongbong.pro.returnedpurchaseproduct.pojo.dto.ReturnedPurchaseProductDeleteBatchDTO;
import com.xbongbong.pro.returnedpurchaseproduct.pojo.vo.ReturnedPurchaseProductDeleteBatchVO;
import com.xbongbong.pro.user.pojo.ReturnUserAndDepartmentPojo;
import com.xbongbong.saas.analytical.impl.ReturnedPurchaseValidateAnalyticalServiceImpl;
import com.xbongbong.saas.annotation.BusinessTypeToServiceAnnotation;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.ProductConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.BusinessProductEntity;
import com.xbongbong.saas.domain.entity.InstockProductEntity;
import com.xbongbong.saas.domain.entity.OutstockProductEntity;
import com.xbongbong.saas.domain.entity.ProductSerialBalanceEntity;
import com.xbongbong.saas.domain.entity.ProductSerialFlowEntity;
import com.xbongbong.saas.domain.entity.PurchaseProductEntity;
import com.xbongbong.saas.domain.entity.ReturnedPurchaseInvoiceEntity;
import com.xbongbong.saas.domain.entity.ReturnedPurchaseProductEntity;
import com.xbongbong.saas.domain.entity.ext.InstockEntityExt;
import com.xbongbong.saas.domain.entity.ext.PayPlanSheetEntityExt;
import com.xbongbong.saas.domain.entity.ext.PaymentSheetEntityExt;
import com.xbongbong.saas.domain.entity.ext.ProductEntityExt;
import com.xbongbong.saas.domain.entity.ext.PurchaseEntityExt;
import com.xbongbong.saas.domain.entity.ext.ReturnedPurchaseEntityExt;
import com.xbongbong.saas.enums.BusinessTypeToServiceEnum;
import com.xbongbong.saas.enums.CompanyConfigEnum;
import com.xbongbong.saas.enums.InOutStockStatusEnum;
import com.xbongbong.saas.enums.OperateModuleTypeEnum;
import com.xbongbong.saas.enums.OperatePageEnum;
import com.xbongbong.saas.enums.OperateTypeEnum;
import com.xbongbong.saas.enums.OutstockTypeEnum;
import com.xbongbong.saas.enums.RedundantTemplateTypeEnum;
import com.xbongbong.saas.enums.RelativeProductEnum;
import com.xbongbong.saas.enums.SelectProductEnum;
import com.xbongbong.saas.enums.UpdateDataTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.InstockEnum;
import com.xbongbong.saas.enums.business.OutstockEnum;
import com.xbongbong.saas.enums.business.PaySheetEnum;
import com.xbongbong.saas.enums.business.PaymentSheetEnum;
import com.xbongbong.saas.enums.business.ProductEnum;
import com.xbongbong.saas.enums.business.PurchaseEnum;
import com.xbongbong.saas.enums.business.PurchaseInvoiceEnum;
import com.xbongbong.saas.enums.business.RefundEnum;
import com.xbongbong.saas.enums.business.ReturnedPurchaseEnum;
import com.xbongbong.saas.enums.business.ReturnedPurchaseOutstockEnum;
import com.xbongbong.saas.enums.business.SerialEnum;
import com.xbongbong.saas.enums.business.SerialStatusEnum;
import com.xbongbong.saas.enums.dictionary.EnableButtonEnum;
import com.xbongbong.saas.enums.dictionary.IsCancelEnum;
import com.xbongbong.saas.enums.dictionary.IsRedEnum;
import com.xbongbong.saas.enums.dictionary.ReturnedStatusEnum;
import com.xbongbong.saas.enums.product.PurchaseProductEnum;
import com.xbongbong.saas.enums.product.ReturnPurchaseProductEnum;
import com.xbongbong.saas.help.BatchSeqExplainHelp;
import com.xbongbong.saas.help.DefaultAttrHelp;
import com.xbongbong.saas.help.ExplainHelp;
import com.xbongbong.saas.help.ImportHelper;
import com.xbongbong.saas.help.LogHandleHelp;
import com.xbongbong.saas.help.ProDetailHandlerHelp;
import com.xbongbong.saas.help.RelativeProductHelp;
import com.xbongbong.saas.help.ReturnPurchaseHelp;
import com.xbongbong.saas.help.SaasDeleteHelp;
import com.xbongbong.saas.help.SaasRefundHelper;
import com.xbongbong.saas.help.SaasSaveHelp;
import com.xbongbong.saas.help.SaasUpdateHelp;
import com.xbongbong.saas.help.workflow.ReturnedPurchaseHelp;
import com.xbongbong.saas.model.InstockModel;
import com.xbongbong.saas.model.InstockProductModel;
import com.xbongbong.saas.model.PayPlanSheetModel;
import com.xbongbong.saas.model.ProductModel;
import com.xbongbong.saas.model.ProductSerialBalanceModel;
import com.xbongbong.saas.model.ProductSerialFlowModel;
import com.xbongbong.saas.model.PurchaseModel;
import com.xbongbong.saas.model.PurchaseProductModel;
import com.xbongbong.saas.model.ReturnedPurchaseInvoiceModel;
import com.xbongbong.saas.model.ReturnedPurchaseModel;
import com.xbongbong.saas.model.ReturnedPurchaseProductModel;
import com.xbongbong.saas.service.FormatSpecialBusinessService;
import com.xbongbong.saas.service.ListBatchService;
import com.xbongbong.saas.service.MobileDetailService;
import com.xbongbong.saas.service.OutstockProductService;
import com.xbongbong.saas.service.ProductSerialService;
import com.xbongbong.saas.service.PurchaseService;
import com.xbongbong.saas.service.ReturnedPurchaseProductService;
import com.xbongbong.saas.service.ReturnedPurchaseService;
import com.xbongbong.saas.service.toolbox.help.LogHelp;
import com.xbongbong.saas.service.toolbox.help.UserTeamHelp;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.workflow.domain.entity.WorkflowEntity;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import static com.xbongbong.saas.toolbox.help.FastJsonHelper.getDoubleFromFormData;
import static com.xbongbong.saas.toolbox.help.FastJsonHelper.getDoubleOrDefaultFromFormData;
import static com.xbongbong.saas.toolbox.help.FastJsonHelper.getIntegerOrDefaultFromFormData;
import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

/**
 * 采购退货单service实现层
 *
 * @author WangJian
 * @version v1.0
 * @date 2019-01-23 20:02
 * @since v1.0
 **/
@Service("ReturnedPurchaseService")
@BusinessTypeToServiceAnnotation(businessService = BusinessTypeToServiceEnum.RETURNED_PURCHASE)
public class ReturnedPurchaseServiceImpl implements ReturnedPurchaseService, FormatSpecialBusinessService {

    private static final Logger LOG = LoggerFactory.getLogger(ReturnedPurchaseServiceImpl.class);

    @Resource
    private DefaultAttrHelp defaultAttrHelp;
    @Resource
    private SaasSaveHelp saasSaveHelp;
    @Resource
    private SaasUpdateHelp saasUpdateHelp;
    @Resource
    private ExplainHelp explainHelp;
    @Resource
    private PurchaseModel purchaseModel;
    @Resource
    private ProductModel productModel;
    @Resource
    private ReturnedPurchaseProductModel returnedPurchaseProductModel;
    @Resource
    private PurchaseService purchaseService;
    @Resource
    private ReturnedPurchaseModel returnedPurchaseModel;
    @Resource
    private ReturnedPurchaseProductService returnedPurchaseProductService;
    @Resource
    private ImportHelper importHelper;
    @Resource
    private OutstockProductService outstockProductService;
    @Resource
    private MongoLogHelp mongoLogHelp;
    @Resource
    @Lazy
    private RuleBusinessLogger ruleBusinessLogger;

    @Resource
    private FormDataValidateProductHelp formDataValidateProductHelp;
    @Resource
    private InstockProductModel instockProductModel;
    @Resource
    private PaasEsModel paasEsModel;
    @Resource
    private PurchaseProductModel purchaseProductModel;
    @Resource
    private PaasFormDataService paasFormDataService;
    @Resource
    private PayPlanSheetModel payPlanSheetModel;

    @Resource
    private ReturnedPurchaseInvoiceModel returnedPurchaseInvoiceModel;
    @Resource
    private XbbElasticsearchRestTemplate xbbElasticsearchRestTemplate;
    @Resource
    private ListBatchService listBatchService;
    @Resource
    private InstockModel instockModel;
    @Resource
    private MobileDetailService mobileDetailService;
    @Resource
    private ProDetailHandlerHelp proDetailHandlerHelp;
    @Resource
    private ProductSerialFlowModel productSerialFlowModel;
    @Resource
    private ProductSerialBalanceModel productSerialBalanceModel;
    @Resource
    private ProductSerialService productSerialService;
    @Resource
    private RelativeProductHelp relativeProductHelp;
    @Resource
    private LogHelp logHelp;
    @Resource
    private LogHandleHelp logHandleHelp;
    @Resource
    private ReturnedPurchaseValidateAnalyticalServiceImpl returnedPurchaseAnalyticalService;
    @Resource
    private ReturnedPurchaseHelp returnedPurchaseHelp;
    @Resource
    private ReturnPurchaseHelp returnPurchaseHelp;
    @Resource
    private SaasRefundHelper saasRefundHelper;
    @Resource
    private UserTeamHelp userTeamHelp;
    @Resource
    private WorkflowFormDataOperationService workflowFormDataOperationService;
    @Resource
    private CommonHelp commonHelp;
    @Resource
    private PaasFormModel paasFormModel;

    /**
     * 采购退货单保存前saas特殊校验
     *
     * @param validateDataDTO saas特殊校验数据入参
     * @author Jian.Wang
     * @date 2019/1/23 20:00
     * @since v1.0
     **/
    @Override
    public void beforeSave(ValidateDataDTO validateDataDTO) throws XbbException {
        returnedPurchaseAnalyticalService.beforeSave(validateDataDTO);
    }




    /**
     * 采购退货单保存后逻辑
     *
     * @param saasFormSaveDTO saas保存数据
     * @author Jian.Wang
     * @date 2019/1/23 20:00
     * @since v1.0
     **/
    @Override
    public void afterSave(SaasFormSaveDTO saasFormSaveDTO, ReturnedPurchaseEntityExt newReturnedPurchaseEntityExt, AssociatedBusinessAfterSavePojo associatedBusinessAfterSavePojo) throws XbbException {
        PaasFormDataEntity paasFormDataEntity = saasFormSaveDTO.getNewPaasFormDataEntity();
        String corpid = saasFormSaveDTO.getCorpid();
        JSONObject data = saasFormSaveDTO.getNewData();
        Long purchaseSheetId = getPurchaseSheetId(data);
        ReturnedPurchaseEntityExt returnedPurchaseEntityExt = new ReturnedPurchaseEntityExt();
        BeanUtil.copyProperties(paasFormDataEntity, returnedPurchaseEntityExt);
        Boolean isNew = saasFormSaveDTO.getIsNew();
        Boolean productCanSee = saasFormSaveDTO.getSaasNeedRedundantAttrPoJo().getAttrCanSee(ReturnedPurchaseEnum.PRODUCTS.getAttr());
        // 有出库单但是没有出库完毕
        Boolean hasOut = !Objects.equals(FastJsonHelper.getLongOrDefaultFromFormData(saasFormSaveDTO.getNewData(),ReturnedPurchaseEnum.OUTSTOCK_ID.getAttr(),0L), 0L);
        //更新采购合同关联退货单id
        PurchaseEntityExt purchase = purchaseModel.getByKey(purchaseSheetId, corpid);
        JSONObject dataList = purchase.getData();
        dataList.put(PurchaseEnum.RETURNED_PURCHASE_ID.getAttr(),purchaseSheetId);
        if (isNew || (productCanSee)){
            // 更新退货产品
            Map<Long, Double> changeNumMap = setReturnedPurchaseProducts(returnedPurchaseEntityExt);
            JSONArray jsonArray = returnedPurchaseEntityExt.getData().getJSONArray(ReturnedPurchaseEnum.PRODUCTS.getAttr());
            List<Long> refList = new ArrayList<>();
            Map<Long, Double> refNumMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            Map<Long, Double> returnProductNumMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            Map<Long, Double> allOldReturnNumMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            Set<Long> noDelList = new HashSet<>();
            if (Objects.nonNull(jsonArray)) {
                for (int i = 0; i < jsonArray.size(); i++) {
                    JSONObject jsonObject = jsonArray.getJSONObject(i);
                    Long pageProductId = jsonObject.getLong(SelectProductEnum.PRODUCT.getAttr());
                    Long refProductId = FastJsonHelper.getLongFromFormData(jsonObject, BusinessConstant.REF_PRODUCT_ID);
                    if (Objects.nonNull(refProductId)) {
                        refList.add(refProductId);
                        noDelList.add(refProductId);
                        refNumMap.put(refProductId, changeNumMap.getOrDefault(refProductId, getDoubleFromFormData(jsonObject, ReturnPurchaseProductEnum.NUM.getAttr())));
                        Double num = returnProductNumMap.getOrDefault(pageProductId, 0D);
                        num = Arith.add(num, changeNumMap.getOrDefault(pageProductId, getDoubleFromFormData(jsonObject, ReturnPurchaseProductEnum.NUM.getAttr())));
                        returnProductNumMap.put(pageProductId, num);
                    }else {
                        Double num = allOldReturnNumMap.getOrDefault(pageProductId, 0D);
                        num += changeNumMap.getOrDefault(pageProductId, getDoubleFromFormData(jsonObject, ReturnPurchaseProductEnum.NUM.getAttr()));
                        allOldReturnNumMap.put(pageProductId, num);
                    }
                }
            }
            for (Map.Entry<Long, Double> entry : changeNumMap.entrySet()) {
                if (!noDelList.contains(entry.getKey())) {
                    refList.add(entry.getKey());
                    refNumMap.put(entry.getKey(), entry.getValue());
                    returnProductNumMap.put(entry.getKey(), entry.getValue());
                }
            }
            if (!refList.isEmpty()) {
                List<PurchaseProductEntity> purchaseProductEntities = purchaseProductModel.getProductsByPurchaseId(corpid, purchaseSheetId);
                Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                params.put("corpid", corpid);
                params.put("idIn", refList);
                params.put("del", DelEnum.NORMAL.getDel());
                List<InstockProductEntity> instockProductEntityList = instockProductModel.findEntitys(params);
//                老数据
                HashSet<Long> oldInstockIds = new HashSet<>();
                Map<Long, Double> refNumsMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                instockProductEntityList.forEach(item -> {
                    if (Objects.nonNull(item.getRefProductId()) && refNumMap.containsKey(item.getId())) {
                        item.setOutstockNum(Arith.add(item.getOutstockNum() == null ? 0D : item.getOutstockNum(), refNumMap.get(item.getId())));
                        refNumsMap.put(item.getRefProductId(), Arith.add(refNumMap.get(item.getId()),refNumsMap.getOrDefault(item.getRefProductId(), 0D)));
                    }else {
                        oldInstockIds.add(item.getIntoWarehouseId());
                    }
                });
                instockProductModel.updateBatch(instockProductEntityList, corpid);
                if (!refNumsMap.isEmpty()){
                    dataList.put(PurchaseEnum.RETURNED_PURCHASE_ID.getAttr(), BasicConstant.ONE);
                    for (PurchaseProductEntity item : purchaseProductEntities) {
                        Double outstockNum = item.getOutstockNum() == null ? 0D : item.getOutstockNum();
                        if (refNumsMap.containsKey(item.getId())) {
                            item.setOutstockNum(Arith.add(outstockNum, refNumsMap.getOrDefault(item.getId(), 0D)));
                        }
                        if (Arith.sub(item.getInstockNum(), item.getOutstockNum()) > 0) {
                            dataList.put(PurchaseEnum.RETURNED_PURCHASE_ID.getAttr(), BasicConstant.ZERO);
                        }
                    }
                    purchaseProductModel.updateBatch(purchaseProductEntities, corpid);
                }
                if (!oldInstockIds.isEmpty()) {
                    params.clear();
                    params.put("corpid", corpid);
                    params.put("idIn", oldInstockIds);
                    params.put("del", DelEnum.NORMAL.getDel());
                    HashSet<Long> purchaseIds = new HashSet<>();
                    List<InstockEntityExt> entitys = instockModel.findEntitys(params);
                    entitys.forEach(item -> {
                        Long purchaseId = item.getData().getLong(InstockEnum.REF_ID.getAttr());
                        purchaseIds.add(purchaseId);
                    });
                    if (!purchaseIds.isEmpty()) {
                        params.clear();
                        params.put("corpid", corpid);
                        params.put("purchaseIdIn", purchaseIds);
                        params.put("del", DelEnum.NORMAL.getDel());
                        List<PurchaseProductEntity> entitys1 = purchaseProductModel.findEntitys(params);

                        for (PurchaseProductEntity entity : entitys1) {
                            if (returnProductNumMap.containsKey(entity.getProductId())) {
                                // 剩余未退
                                Double unStockNum = Arith.sub(entity.getProductNum(), entity.getOutstockNum());
                                Double amendNum = returnProductNumMap.get(entity.getProductId());
                                Double outstocknNum;
                                Double inNum = Arith.sub(amendNum, unStockNum);
                                if (inNum > 0) {
                                    outstocknNum = entity.getProductNum();
                                    returnProductNumMap.put(entity.getProductId(), inNum);
                                }else {
                                    outstocknNum = Arith.add(entity.getOutstockNum(), amendNum);
                                    returnProductNumMap.remove(entity.getProductId());
                                }
                                entity.setOutstockNum(outstocknNum);
                                entity.setUpdateTime(DateTimeUtil.getInt());
                            }
                        }
                        purchaseProductModel.updateBatch(entitys1, corpid);
                    }

                }

            }

            if (!allOldReturnNumMap.isEmpty()) {
                //             采购退货没有refproductid的情况

                Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                params.put("corpid", corpid);
                params.put("purchaseSheetId", purchaseSheetId);
                params.put("del", DelEnum.NORMAL.getDel());
                List<PurchaseProductEntity> entitys = purchaseProductModel.findEntitys(params);
                entitys.forEach(item ->{
                    if (allOldReturnNumMap.containsKey(item.getProductId())) {
                        // 剩余未退
                        Double unStockNum = Arith.sub(item.getProductNum(), item.getOutstockNum());
                        Double amendNum = allOldReturnNumMap.get(item.getProductId());
                        Double outstockNum;
                        Double outNum = Arith.sub(amendNum, unStockNum);
                        if (outNum > 0) {
                            outstockNum = item.getProductNum();
                            allOldReturnNumMap.put(item.getProductId(), outNum);
                        }else {
                            outstockNum = Arith.add(item.getOutstockNum(), amendNum);
                            allOldReturnNumMap.remove(item.getProductId());
                        }
                        item.setOutstockNum(outstockNum);
                        item.setUpdateTime(DateTimeUtil.getInt());
                    }
                });
                purchaseProductModel.updateBatch(entitys, corpid);
            }

        }
        purchaseModel.save(purchase);
        // 看不懂这里的意义
        /*if (!isNew) {
            if (purchaseSheetId != null) {
                PurchaseEntityExt originalPurchase = purchaseModel.getByKey(purchaseSheetId, corpid);
                if (originalPurchase != null) {
                    JSONObject purchaseData = originalPurchase.getData();
                    purchaseData.put(PurchaseEnum.RETURNED_PURCHASE_ID.getAttr(),0);
                    originalPurchase.setData(purchaseData);
                    purchaseModel.save(originalPurchase);
                }
            }

        }*/
        if (isNew) {
            ReRollBackEntity reRollBackEntity = associatedBusinessAfterSavePojo.getReRollBackEntity();
            //关联红冲付款单新建
            List<Long> redPaySheetIds = generateRedPay(associatedBusinessAfterSavePojo.getSheetArray(), saasFormSaveDTO);
            reRollBackEntity.setRedSheetId(redPaySheetIds);
            // --关联发票红冲/作废--*/
            List<Long> invoiceIds = saveReturnedPurchaseInvoice(saasFormSaveDTO, associatedBusinessAfterSavePojo.getInvoiceArray());
            reRollBackEntity.setRedInvoiceId(invoiceIds);
            JSONObject returnedPurchaseData = newReturnedPurchaseEntityExt.getData();
            // 更新采购退货中关联发票和关联红冲付款单字段内容（红冲发票和红冲付款单属于新建，其id在新建成功后才能拿到）
            if (!invoiceIds.isEmpty()) {
                returnedPurchaseData.put(ReturnedPurchaseEnum.INVOICES.getAttr(), invoiceIds);
            } else {
                returnedPurchaseData.put(ReturnedPurchaseEnum.INVOICES.getAttr(), null);
                returnedPurchaseData.put(ReturnedPurchaseEnum.INVOICES_LINKED_TEXT.getAttr(), null);
            }
            if (!redPaySheetIds.isEmpty()) {
                returnedPurchaseData.put(ReturnedPurchaseEnum.PAY_SHEETS.getAttr(), redPaySheetIds);
                if (associatedBusinessAfterSavePojo.getRefundAmount() != null) {
                    returnedPurchaseData.put(ReturnedPurchaseEnum.RETURNED_PURCHASE_AMOUNT.getAttr(), associatedBusinessAfterSavePojo.getRefundAmount());
                }
            } else {
                returnedPurchaseData.put(ReturnedPurchaseEnum.PAY_SHEETS.getAttr(), null);
                returnedPurchaseData.put(ReturnedPurchaseEnum.PAY_SHEETS_LINKED_TEXT.getAttr(), null);
            }
            JSONArray productArray = saasSaveHelp.formatSelectProduct4Save2(returnedPurchaseData, ReturnedPurchaseEnum.PRODUCTS.getAttr());
            newReturnedPurchaseEntityExt.setData(returnedPurchaseData);
            returnedPurchaseModel.update(newReturnedPurchaseEntityExt);
            newReturnedPurchaseEntityExt.getData().put(ReturnedPurchaseEnum.PRODUCTS.getAttr(), productArray);
        }
    }




    /**
     * 采购退货单参数保存前对相关参数进行合理化校验
     *
     * @param validateDataDTO 前端传参数据
     * @throws XbbException 参数不符合要求错误提醒
     * @author Jian.Wang
     * @date 2019/2/21 10:04
     * @since v1.0
     */
    private void parameterCheck(ValidateDataDTO validateDataDTO) throws XbbException {
        JSONObject data = validateDataDTO.getData();
        if (data == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100015);
        }
//        String sheetNo = saasUpdateHelp.getStringFromFormData(data, ReturnedPurchaseEnum.SHEET_NO.getAttr());
//        if (sheetNo.length() > SHEET_NO_LENGTH_MAX) {
//            throw new XbbException(ReturnedPurchaseErrorCodeEnum.API_ERROR_230009);
//        }
    }

    /**
     * 采购退货单根据传入参数将冗余数据存入data中，方便使用时获取
     *
     * @param validateDataDTO 前端传参数据
     * @throws XbbException 参数不符合要求错误提醒
     * @author Jian.Wang
     * @date 2019/2/21 10:04
     * @since v1.0
     */
    private void redundantDataProcessing(ValidateDataDTO validateDataDTO) throws XbbException{
        String corpid = validateDataDTO.getCorpid();
        JSONObject data = validateDataDTO.getData();
        if (data == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100015);
        }
        // 获取到采购合同的ID
        Long purchaseId = getPurchaseSheetId(data);
        PurchaseEntityExt purchaseEntityExt = purchaseModel.getByKey(purchaseId, corpid);
        if (null == purchaseEntityExt) {
            throw new XbbException(PurchaseErrorCodeEnum.API_ERROR_225025);
        }
        JSONObject dataList = purchaseEntityExt.getData();
        Long supplierId = dataList.getLong(PurchaseEnum.SUPPLIER_ID.getAttr());
        data.put(ReturnedPurchaseEnum.SUPPLIER_ID.getAttr(),supplierId);
        validateDataDTO.setData(data);
    }

    /**
     * 获取采购合同ID
     *
     * @param data 数据源
     * @return Long 采购合同ID
     * @author Jian.Wang
     */
    private Long getPurchaseSheetId(JSONObject data) throws XbbException {
        if (null == data) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100015);
        }
        Long purchaseId = FastJsonHelper.getLongFromFormData(data, ReturnedPurchaseEnum.PURCHASE_SHEET_ID.getAttr());
        if (null == purchaseId) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100015);
        }
        return purchaseId;
    }

    /**
     * 退货数量校验
     */
    private void checkReturnProductNum(ValidateDataDTO validateDataDTO, JSONArray productArray,Map<Long, ProductEntityExt> productMap,Map<Long, PurchaseProductEntity> purchaseProductMap) throws XbbException {
        String corpid = validateDataDTO.getCorpid();
        Long dataId = validateDataDTO.getDataId();
        boolean isEdit = Objects.nonNull(dataId) && !Objects.equals(dataId, 0L);
        Map<Long, OutstockProductEntity> outstockProductMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (isEdit) {
            List<OutstockProductEntity> alreadyOutstockProduct = outstockProductService.getAlreadyOutstockProduct(corpid, dataId, OutstockTypeEnum.RETURNED_PURCHASE_OUTSTOCK.getCode());
            alreadyOutstockProduct.forEach(outstockProductEntity -> outstockProductMap.put(outstockProductEntity.getProductId(), outstockProductEntity));
        }

        for (int i = 0; i < productArray.size(); i++) {
            JSONObject productObj = productArray.getJSONObject(i);
            Long productId = productObj.getLong(StringConstant.SAAS_LINK_BUSINESS_ID);
            if (!RegexUtil.isNumber(productObj.getString(RelativeProductEnum.NUM.getSaasAttr()))) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100018, MessageConstant.DATA_NOT_STANDARD, RelativeProductEnum.NUM.getAttrName());
            }
            Double productNum = productObj.getDouble(RelativeProductEnum.NUM.getSaasAttr());

            ProductEntityExt product = productMap.get(productId);
            if (Objects.isNull(product)) {
                throw new XbbException(ProductErrorCodeEnum.API_ERROR_205018);
            }
            JSONObject dataList = product.getData();
            String productName = Objects.toString(dataList.getString(ProductEnum.NAME.getAttr()), "");
            if (Objects.equals(1, product.getDel())) {
                throw new XbbException(ProductErrorCodeEnum.API_ERROR_205018, productName + ProductErrorCodeEnum.API_ERROR_205033.getMsg());
            }
            if (purchaseProductMap.containsKey(productId)) {
                PurchaseProductEntity purchaseProduct = purchaseProductMap.get(productId);
                //已入库数量了
                Double instockNum = purchaseProduct.getProductNum();
                if (Double.compare(productNum, instockNum) > 0) {
                    throw new XbbException(ProductErrorCodeEnum.API_ERROR_205034, String.format(ProductErrorCodeEnum.API_ERROR_205034.getMsg(), productName));
                }
            } else {
                throw new XbbException(ReturnedPurchaseErrorCodeEnum.API_ERROR_230021, ReturnedPurchaseErrorCodeEnum.API_ERROR_230021.getMsg(), productName);
            }
            if (isEdit) {
                if (outstockProductMap.containsKey(productId)) {
                    OutstockProductEntity outStockProduct = outstockProductMap.get(productId);
                    Double outstockNum = outStockProduct.getProductNum();
                    if (Double.compare(productNum, outstockNum) < 0) {
                        throw new XbbException(ReturnedPurchaseErrorCodeEnum.API_ERROR_230018, String.format(ReturnedPurchaseErrorCodeEnum.API_ERROR_230018.getMsg(), productName));
                    }
                }
            }
        }
    }
    /**
     * 更新退货单产品
     *
     * @param returnedPurchaseEntityExt     前端传入的数据
     * @author Jian.Wang
     * @date  2019/2/21 22:01
     */
    private Map<Long, Double> setReturnedPurchaseProducts(ReturnedPurchaseEntityExt returnedPurchaseEntityExt) throws XbbException {
        String corpid = returnedPurchaseEntityExt.getCorpid();
        Long dataId = returnedPurchaseEntityExt.getId();
        JSONObject returnedPurchaseData = returnedPurchaseEntityExt.getData();
        JSONArray productArray = returnedPurchaseData.getJSONArray(ReturnedPurchaseEnum.PRODUCTS.getAttr());
        // 产品数据留个副本，给序列号用
        Map<String, Object> modelMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        modelMap.put("corpid", corpid);
        modelMap.put("returnPurchaseId", dataId);
        modelMap.put("del", 0);
        List<ReturnedPurchaseProductEntity> returnedPurchaseProductEntityList = returnedPurchaseProductModel.findEntitys(modelMap);
        Map<Long, ReturnedPurchaseProductEntity> orginProductMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (ReturnedPurchaseProductEntity returnedPurchaseProductEntity : returnedPurchaseProductEntityList) {
            orginProductMap.put(returnedPurchaseProductEntity.getId(), returnedPurchaseProductEntity);
        }
        List<ReturnedPurchaseProductEntity> productAddList = new ArrayList<>();
        List<ReturnedPurchaseProductEntity> productUpdateList = new ArrayList<>();
        Map<Long, PaasFormDataEntityExt> productMap = formDataValidateProductHelp.product2saveMap(corpid,productArray);
        Integer sort = 0;
        Map<Long, Double> changeNumMap = new HashMap<>(productArray.size());
        for (int i = 0; i < productArray.size(); i++) {
            JSONObject jsonObject = productArray.getJSONObject(i);
            JSONArray seqArray = jsonObject.getJSONArray(ProductConstant.SEQ);
            int enableSerialNumber = jsonObject.getIntValue(ProductEnum.ENABLE_SERIAL_NUMBER.getSaasAttr());
            // 移除序列号相关数据，不存入关联产品数据中
            jsonObject.remove(ProductConstant.SEQ);
            jsonObject.remove(ProductEnum.ENABLE_SERIAL_NUMBER.getSaasAttr());
            jsonObject.remove(ProductEnum.ENABLE_BATCH_SHELF_LIFE.getSaasAttr());

            Long pageProductId = jsonObject.getLong(ReturnPurchaseProductEnum.PRODUCT.getAttr());
            Long businessProductId = jsonObject.getLong(BusinessConstant.PRODUCT_SUB_ID);
            Double productNum = jsonObject.getDouble(ReturnPurchaseProductEnum.NUM.getAttr());
//            String memo = jsonObject.getString(ReturnPurchaseProductEnum.MEMO.getAttr());
            boolean addProductFlag = formDataValidateProductHelp.addProductFlag(businessProductId);
            ReturnedPurchaseProductEntity returnedPurchaseProductEntity;
            Double originNum = 0D;
            if (addProductFlag) {
                //新增产品
                returnedPurchaseProductEntity = new ReturnedPurchaseProductEntity();
                productAddList.add(returnedPurchaseProductEntity);
            } else if (orginProductMap.containsKey(businessProductId)) {
                //编辑产品
                returnedPurchaseProductEntity = orginProductMap.get(businessProductId);
                productUpdateList.add(returnedPurchaseProductEntity);
                originNum = returnedPurchaseProductEntity.getProductNum();
                //只剩删除的产品
                orginProductMap.remove(businessProductId);
            } else {
                //删除产品
                continue;
            }
            JSONObject productData = productMap.get(pageProductId).getData();
            Integer enableMultiUnit = productData.getInteger(ProductEnum.ENABLE_MULTI_UNIT.getAttr());
            if (Objects.equals(enableMultiUnit, 1)) {
                formDataValidateProductHelp.setBusinessUnit(jsonObject, returnedPurchaseProductEntity);
                returnedPurchaseProductEntity.setProductUnit(jsonObject.getString(SelectProductEnum.UNIT.getAttr()));
            } else {
                returnedPurchaseProductEntity.setProductUnit(productData.getString(ProductEnum.UNIT.getAttr()));
                jsonObject.put(PurchaseProductEnum.UNIT.getAttr(),productData.getString(ProductEnum.UNIT.getAttr()));
            }
            returnedPurchaseProductEntity.setAddTime(DateTimeUtil.getInt());
            returnedPurchaseProductEntity.setUpdateTime(DateTimeUtil.getInt());
            returnedPurchaseProductEntity.setDel(0);
            returnedPurchaseProductEntity.setParentId(productData.getLong(ProductEnum.PARENT_ID.getAttr()));
            returnedPurchaseProductEntity.setProductId(pageProductId);
            returnedPurchaseProductEntity.setProductName(FastJsonHelper.getStringOrDefaultFromFormData(productData, ProductEnum.NAME.getAttr(), ""));
            returnedPurchaseProductEntity.setProductNo(productMap.get(pageProductId).getSerialNo());
            returnedPurchaseProductEntity.setProductSpecification(FastJsonHelper.getStringOrDefaultFromFormData(productData, ProductEnum.SPECIFICATION_LINK_TEXT.getAttr(), ""));
            String unit = FastJsonHelper.getStringOrDefaultFromFormData(productData, ProductEnum.UNIT.getAttr(), "");
            saasSaveHelp.formatLinkBusiness4Save(jsonObject, ReturnPurchaseProductEnum.WAREHOUSE.getAttr(),"warehouseName",FieldTypeEnum.LINK_BUSINESS_SINGLE.getType());
//            returnedPurchaseProductEntity.setProductUnit(unit);
            returnedPurchaseProductEntity.setProductNum(productNum);
            returnedPurchaseProductEntity.setReturnPurchaseId(dataId);
            returnedPurchaseProductEntity.setCorpid(corpid);
            returnedPurchaseProductEntity.setMoney(Arith.mul(jsonObject.getDouble(ReturnPurchaseProductEnum.PURCHASE_PRICE.getAttr()), productNum));
            returnedPurchaseProductEntity.setProductPrice(jsonObject.getDouble(ReturnPurchaseProductEnum.PURCHASE_PRICE.getAttr()));
            returnedPurchaseProductEntity.setMemo(jsonObject.getString(ReturnPurchaseProductEnum.MEMO.getAttr()));
            returnedPurchaseProductEntity.setSort(sort);
//            jsonObject.put(ReturnedPurchaseOutstockProductEnum.UNIT.getAttr(),unit);
            returnedPurchaseProductEntity.setData(jsonObject);
            if (Objects.nonNull(jsonObject.getLong(BusinessConstant.REF_PRODUCT_ID))) {
                returnedPurchaseProductEntity.setRefProductId(jsonObject.getLong(BusinessConstant.REF_PRODUCT_ID));
                changeNumMap.put(jsonObject.getLong(BusinessConstant.REF_PRODUCT_ID), Arith.sub(productNum, originNum));
            }
            if (addProductFlag) {
                returnedPurchaseProductModel.insert(returnedPurchaseProductEntity);
                // 新增序列号，关联产品不保存序列号，但是后面序列号保存以及生成出入库单需要序列号数据，所以给他加回去
                if (Objects.nonNull(seqArray) && !seqArray.isEmpty()) {
                    jsonObject.put(ProductConstant.SEQ, seqArray);
                    jsonObject.put(ProductEnum.ENABLE_SERIAL_NUMBER.getSaasAttr(), enableSerialNumber);
                }
            }
            sort++;
        }
//        for (ReturnedPurchaseProductEntity addProduct : productAddList) {
//            returnedPurchaseProductModel.insert(addProduct);
//        }
        for (ReturnedPurchaseProductEntity updateProduct : productUpdateList) {
            returnedPurchaseProductModel.update(updateProduct);
        }
        for (Map.Entry<Long, ReturnedPurchaseProductEntity> entry : orginProductMap.entrySet()) {
            ReturnedPurchaseProductEntity delProduct = entry.getValue();
            changeNumMap.put(delProduct.getRefProductId(), Arith.sub(0D, delProduct.getProductNum()));
            // 删除产品时，更新序列号结存记录，删除序列号流水记录
            updateSerial(delProduct);
            returnedPurchaseProductModel.deleteByKey(delProduct.getId(), delProduct.getCorpid());
        }
        if (CollectionUtils.isNotEmpty(productAddList)) {
            for (ReturnedPurchaseProductEntity addProduct : productAddList) {
                saveSerial(addProduct, returnedPurchaseEntityExt);
            }
        }
        return changeNumMap;
    }

    /**
     * 编辑采购退货单删除的产品序列号处理
     * @param delProduct 删除关联产品
     */
    private void updateSerial(ReturnedPurchaseProductEntity delProduct) throws XbbException {
        productSerialFlowModel.delByRefProductAndBusinessType(delProduct.getCorpid(), delProduct.getId(), XbbRefTypeEnum.RETURNED_PURCHASE.getCode());

        List<ProductSerialBalanceEntity> balanceEntities = productSerialBalanceModel.getByRefProductId(delProduct.getId(), XbbRefTypeEnum.RETURNED_PURCHASE.getCode(), delProduct.getCorpid());
        if (Objects.nonNull(balanceEntities)) {
            for (ProductSerialBalanceEntity entity : balanceEntities) {
                String seqKey = entity.getSeqKey();

                ProductSerialFlowEntity lastSerialFlow = productSerialFlowModel.getLastSerialFlow(delProduct.getCorpid(), seqKey, entity.getRefId());
                entity.setRefId(lastSerialFlow.getRefId());
                entity.setBusinessType(lastSerialFlow.getBusinessType());
                entity.setRefProductId(lastSerialFlow.getRefProductId());
                entity.setAddTime(lastSerialFlow.getAddTime());
                entity.setUpdateTime(lastSerialFlow.getUpdateTime());
                entity.setDate(lastSerialFlow.getDate());
                entity.setWarehouseId(lastSerialFlow.getWarehouseId());
                productSerialBalanceModel.update(entity);
            }
        }
    }

    private void saveSerial(ReturnedPurchaseProductEntity returnedPurchaseProductEntity, ReturnedPurchaseEntityExt returnedPurchaseEntityExt) throws XbbException {
        Long dataId = returnedPurchaseEntityExt.getId();
        String corpid = returnedPurchaseEntityExt.getCorpid();
        JSONObject returnedPurchaseData = returnedPurchaseEntityExt.getData();
        JSONObject productData = returnedPurchaseProductEntity.getData();

        List<ProductSerialFlowEntity> productSerialFlowEntityList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<String, ProductSerialFlowEntity> productSerialFlowEntityMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        //
        List<ProductSerialFlowEntity> flowEntityList = productSerialFlowModel.getFlowByRefIdAndBusiness(Collections.singletonList(dataId), XbbRefTypeEnum.RETURNED_PURCHASE.getCode(), corpid);
        List<String> serialList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (CollectionUtils.isNotEmpty(flowEntityList)) {
            flowEntityList.forEach(item -> serialList.add(item.getSeqKey()));
        }
        Set<String> seqKeyList = new HashSet<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);

        JSONArray seqArray = productData.getJSONArray(ProductConstant.SEQ);
        if (BasicConstant.ZERO.equals(productData.getIntValue(ProductEnum.ENABLE_SERIAL_NUMBER.getSaasAttr())) && (Objects.isNull(seqArray) || seqArray.isEmpty())) {
            return;
        }
        Long productId = productData.getLong(ReturnPurchaseProductEnum.PRODUCT.getAttr());
        for (int j = 0; j < seqArray.size(); j++) {
            JSONObject seqData = seqArray.getJSONObject(j);
            String serial = seqData.getString(SerialEnum.SERIAL.getAttr());
            String seqKey = productId + "_" + serial;
            if (serialList.contains(seqKey)) {
                throw new XbbException(ProductErrorCodeEnum.API_ERROR_205094, String.format(ProductErrorCodeEnum.API_ERROR_205094.getMsg(), serial));
            }
            ProductSerialFlowEntity productSerialFlowEntity = new ProductSerialFlowEntity();
            productSerialFlowEntity.setCorpid(corpid);
            productSerialFlowEntity.setProductId(productId);
            productSerialFlowEntity.setSeq(serial);
            productSerialFlowEntity.setMemo(seqData.getString(SerialEnum.MEMO.getAttr()));
            productSerialFlowEntity.setStatus(SerialStatusEnum.IN_STOCK.getCode());
            productSerialFlowEntity.setDate(DateTimeUtil.getInt());
            productSerialFlowEntity.setBusinessType(XbbRefTypeEnum.RETURNED_PURCHASE.getCode());
            productSerialFlowEntity.setRefId(dataId);
            // 关联产品id
            productSerialFlowEntity.setRefProductId(returnedPurchaseProductEntity.getId());
            productSerialFlowEntity.setRefSheetNo(returnedPurchaseEntityExt.getSerialNo());
            productSerialFlowEntity.setParentId(returnedPurchaseProductEntity.getParentId());

            saasSaveHelp.formatLinkBusiness4Save(productData, ReturnPurchaseProductEnum.WAREHOUSE.getAttr(), "warehouseName", FieldTypeEnum.LINK_BUSINESS_SINGLE.getType());
            productSerialFlowEntity.setWarehouseId(productData.getLongValue(ReturnPurchaseProductEnum.WAREHOUSE.getAttr()));
            productSerialFlowEntity.setWarehouseName(productData.getString("warehouseName"));
            productSerialFlowEntity.setBusinessId(returnedPurchaseData.getLong(ReturnedPurchaseEnum.SUPPLIER_ID.getAttr()));
            productSerialFlowEntity.setBusinessName(returnedPurchaseData.getString(ReturnedPurchaseEnum.LINK_SUPPLIER_HIDE.getAttr()));
            productSerialFlowEntity.setSeqKey(seqKey);
            productSerialFlowEntity.setDel(BasicConstant.ZERO);

            seqKeyList.add(productSerialFlowEntity.getSeqKey());
            productSerialFlowEntityList.add(productSerialFlowEntity);
            productSerialFlowEntityMap.put(productSerialFlowEntity.getSeqKey(), productSerialFlowEntity);
        }

        if (CollectionUtils.isNotEmpty(productSerialFlowEntityList)) {
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", corpid);
            param.put("seqKeyIn", seqKeyList);
            param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
            // 结存记录
            List<ProductSerialBalanceEntity> entitys = productSerialBalanceModel.findEntitys(param);
            for (ProductSerialBalanceEntity entity : entitys) {
                ProductSerialFlowEntity productSerialFlowEntity = productSerialFlowEntityMap.get(entity.getSeqKey());
                entity.setStatus(productSerialFlowEntity.getStatus());
                entity.setBusinessType(productSerialFlowEntity.getBusinessType());
                entity.setRefId(productSerialFlowEntity.getRefId());
                entity.setRefSheetNo(productSerialFlowEntity.getRefSheetNo());
                entity.setRefProductId(productSerialFlowEntity.getRefProductId());
                entity.setDate(productSerialFlowEntity.getDate());
                // 反向操作一波，仓库不变
                productSerialFlowEntity.setWarehouseId(entity.getWarehouseId());
            }
            // 新增流水
            productSerialFlowModel.insertBatch(productSerialFlowEntityList);
            // 更新结存
            productSerialBalanceModel.updateBatch(entitys, corpid);
        }
    }



    /**
     * 更新退货单产品信息
     *
     * @param returnedPurchaseProduct 退货单关联产品
     * @param products                退货单产品id对应产品库中产品
     * @return 更新后的退货单产品
     */
    private ReturnedPurchaseProductEntity setLatestParam(ReturnedPurchaseProductEntity returnedPurchaseProduct, List<ProductEntityExt> products) throws XbbException {
        for (ProductEntityExt product : products) {
            if (returnedPurchaseProduct.getProductId().equals(product.getId())) {
                JSONObject dataList = product.getData();
                ProductEntityExt parentProduct = productModel.getByKey(dataList.getLong(ProductEnum.PARENT_ID.getAttr()), returnedPurchaseProduct.getCorpid());
                if (Objects.isNull(parentProduct)) {
                    LOG.error("父产品不存在");
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, "父产品不存在");
                }
                JSONObject parentProductData = parentProduct.getData();
                // 规格用子产品的具体规格
                String specification = dataList.getString(ProductEnum.SPECIFICATION_LINK_TEXT.getAttr());
                returnedPurchaseProduct.setProductSpecification(StringUtil.isEmpty(specification) ? "{}" : specification);
                String barcode = Objects.toString(dataList.getString(ProductEnum.BARCODE.getAttr()));
                returnedPurchaseProduct.setBarcode(barcode);
                String name = parentProductData.getString(ProductEnum.NAME.getAttr());
                returnedPurchaseProduct.setProductName(StringUtil.isEmpty(name) ? "" : name);
                String unit = parentProductData.getString(ProductEnum.UNIT.getAttr());
                returnedPurchaseProduct.setProductUnit(StringUtil.isEmpty(unit) ? "" : unit);
                String productNo = parentProductData.getString(ProductEnum.PRODUCT_NO.getAttr());
                returnedPurchaseProduct.setProductNo(StringUtil.isEmpty(productNo) ? "" : productNo);
            }
        }
        return returnedPurchaseProduct;
    }

//    /**
//     * 编辑保存数据回显
//     * @param dataList  要返回的jsonobject
//     * @param saasAnalysisDataDTO 编辑数据
//     * @author Jian.Wang
//     * @date 2019/2/26 20:39
//     */
//    private void formatProduct4Show(JSONObject dataList, SaasAnalysisDataDTO saasAnalysisDataDTO) throws XbbException{
//        if (dataList == null || saasAnalysisDataDTO == null) {
//            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100002);
//        }
//        // 获取采购退货单关联产品
//        BusinessProductListDTO businessProductListDTO = new BusinessProductListDTO();
//        BeanUtil.copyProperties(saasAnalysisDataDTO, businessProductListDTO);
//        BusinessProductListVO businessProductListVO;
//        if (saasAnalysisDataDTO.getForProcess()) {
//            businessProductListVO = getReturnedPurchaseProductList(businessProductListDTO, dataList);
//        } else {
//            businessProductListVO = getReturnedPurchaseProductList(businessProductListDTO, null);
//        }
//        JSONObject productFinalObj = businessProductListVO.getProduct();
//        // 将数据的顺序和解释的顺序保持一致
//        JSONArray productArray = productFinalObj.getJSONArray(StringConstant.PRODUCT_LIST);
//        BusinessProductEnum businessProductEnum = BusinessProductEnum.getByCode(XbbRefTypeEnum.RETURNED_PURCHASE.getCode());
//        for (int i=0; i<productArray.size(); i++) {
//            JSONObject productObj = productArray.getJSONObject(i);
//            JSONArray attrArray = productObj.getJSONArray(StringConstant.RESULT);
//            JSONArray sortedAttrArray = new JSONArray();
//            for (RelativeProductEnum attrEnum : businessProductEnum.getList()) {
//                String saasAttr = attrEnum.getSaasAttr();
//                attrArray.forEach(item -> {
//                    JSONObject itemObj = (JSONObject) item;
//                    if (Objects.equals(itemObj.getString("attr"), saasAttr)) {
//                        sortedAttrArray.add(item);
//                    }
//                });
//            }
//            productObj.put(StringConstant.RESULT, sortedAttrArray);
//        }
//        dataList.put(ReturnedPurchaseEnum.PRODUCTS.getAttr(), productFinalObj);
//    }

    @Override
    public PagingProductVO getPagingProduct(PagingProductDTO pagingProductDTO) throws XbbException {
        PagingProductVO pagingProductVO = new PagingProductVO();
        Map<String, Object> modelMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        modelMap.put(ParameterConstant.CORPID, pagingProductDTO.getCorpid());
        modelMap.put(ParameterConstant.RETURN_PURCHASE_ID, pagingProductDTO.getDataId());
        modelMap.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        modelMap.put(ParameterConstant.PAGE,  pagingProductDTO.getPage());
        modelMap.put(ParameterConstant.ORDER_BY_STR, BasicConstant.SORT);
        PageHelper pageHelper = PageHelperUtil.getPageHelper(modelMap, returnedPurchaseProductModel, pagingProductDTO.getPageSize());
        List<ReturnedPurchaseProductEntity> returnedPurchaseProductEntityList = (List<ReturnedPurchaseProductEntity>) PageHelperUtil.getEntityList(modelMap, pageHelper, returnedPurchaseProductModel);
        if (pagingProductDTO.getUpdateDataTypeEnum().isDetail()) {
            DetailProductVO detailProductVO = formatProduct4DetailShow(returnedPurchaseProductEntityList, pagingProductDTO);
            pagingProductVO.setProductDataArr(detailProductVO.getProductDataArr());
        }
        pagingProductVO.setPageHelper(pageHelper);
        return pagingProductVO;
    }

    public DetailProductVO formatProduct4DetailShow(List<ReturnedPurchaseProductEntity> returnedPurchaseProductEntityList, PagingProductDTO pagingProductDTO) throws XbbException{
        DetailProductVO detailProductVO = new DetailProductVO();
        Set<Long> productIds = new HashSet<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (ReturnedPurchaseProductEntity purchaseProductEntity : returnedPurchaseProductEntityList) {
            productIds.add(purchaseProductEntity.getProductId());
        }
        String corpid = pagingProductDTO.getCorpid();
        JSONArray productArray = new JSONArray();
        for (ReturnedPurchaseProductEntity returnedPurchaseProductEntity : returnedPurchaseProductEntityList) {
            JSONObject json = new JSONObject();
            Double rate = 1D;
            if (Objects.nonNull(returnedPurchaseProductEntity.getData())) {
                json = returnedPurchaseProductEntity.getData();
            }
            if (Objects.nonNull(returnedPurchaseProductEntity.getBusinessUnit())) {
                returnedPurchaseProductEntity.setProductNum(Arith.div(returnedPurchaseProductEntity.getProductNum(), returnedPurchaseProductEntity.getRate()));
                returnedPurchaseProductEntity.setProductUnit(returnedPurchaseProductEntity.getBusinessUnit().toString());
                rate = returnedPurchaseProductEntity.getRate();
                JSONObject priceData = returnedPurchaseProductEntity.getPriceData();
                if (Objects.nonNull(priceData) && !priceData.isEmpty()) {
                    returnedPurchaseProductEntity.setProductPrice(priceData.getDouble(SelectProductEnum.PRICE.getAttr()));
                }
            }
            for (ReturnPurchaseProductEnum returnPurchaseProductEnum : ReturnPurchaseProductEnum.values()) {
                if (!UpdateDataTypeEnum.DETAIL.formatShow(returnPurchaseProductEnum.getShowType())) {
                    continue;
                }
                String attr = returnPurchaseProductEnum.getAttr();
                switch (returnPurchaseProductEnum) {
                    case PRODUCT:
                        json.put(attr, returnedPurchaseProductEntity.getProductId());
                        break;
                    case PURCHASE_PRICE:
                        json.put(attr, returnedPurchaseProductEntity.getProductPrice());
                        break;
                    case NUM:
                        json.put(attr, returnedPurchaseProductEntity.getProductNum());
                        break;
                    case SUBTOTAL:
                        json.put(attr, Arith.mul(returnedPurchaseProductEntity.getProductNum(), returnedPurchaseProductEntity.getProductPrice()));
                        break;
                    case MEMO:
                        json.put(attr, returnedPurchaseProductEntity.getMemo());
                        break;
                    case UNIT:
                        json.put(attr, returnedPurchaseProductEntity.getProductUnit());
                        break;
                    case OUTSTOCK_NUM:
                        json.put(attr, Arith.div(returnedPurchaseProductEntity.getOutstockNum(), rate));
                        break;
                    case WAIT_OUTSTOCK_NUM:
                        json.put(attr,Arith.sub(returnedPurchaseProductEntity.getProductNum(), Arith.div(returnedPurchaseProductEntity.getOutstockNum(), rate)));
                        break;
//                    case PRODUCE_DATE:
//                        if (Objects.nonNull(json.get(SelectProductEnum.PRODUCE_DATE.getAttr()))) {
//                            Long guaranteePeriod = json.getLong(SelectProductEnum.PRODUCE_DATE.getAttr());
//                            String produceDateStr = DateTimeUtil.getStringEpochSecond(guaranteePeriod, DateTimeUtil.SDFDate);
//                            json.put(SelectProductEnum.PRODUCE_DATE.getAttr(), produceDateStr);
//                        }
//                        break;
                    case RETURN_STATUS:
                        if (returnedPurchaseProductEntity.getOutstockNum() > 0) {
                            if (Double.compare(returnedPurchaseProductEntity.getProductNum(), Arith.div(returnedPurchaseProductEntity.getOutstockNum(), rate)) > 0) {
                                json.put(attr, I18nMessageUtil.getMessage(I18nStringConstant.PARTIAL_DELIVERY));
                            } else {
                                json.put(attr, I18nMessageUtil.getMessage(I18nStringConstant.ISSUE_ALL));
                            }
                        } else {
                            json.put(attr, InOutStockStatusEnum.UN_OUTSTOCK.getName());
                        }
                        break;
                    default:
                        break;
                }
            }
            if (Objects.equals(json.getDouble(SelectProductEnum.GUARANTEE_PERIOD.getAttr()), 0D)) {
                if (Objects.equals(json.getLong(SelectProductEnum.PRODUCE_DATE.getAttr()), 0L) || Objects.isNull(json.get(SelectProductEnum.PRODUCE_DATE.getAttr()))) {
                    json.remove(SelectProductEnum.GUARANTEE_PERIOD.getAttr());
                }
            }
            json.put(BusinessConstant.PRODUCT_SUB_ID, returnedPurchaseProductEntity.getId());
            productArray.add(json);
        }
        detailProductVO.setProductDataArr(productArray);
        return detailProductVO;
    }

    @Override
    public void formatProduct4Show2(Long dataId, String corpid, JSONObject data, Boolean forProcess, Integer operate, UpdateDataTypeEnum updateDataTypeEnum) throws XbbException {
        returnedPurchaseModel.formatProduct4Show2(dataId, corpid, data, forProcess, operate, updateDataTypeEnum);
    }

    @Override
    public JSONObject formatSingleProduct(ReturnedPurchaseProductEntity returnedPurchaseProductEntity, Boolean isEdit) {
        return returnedPurchaseModel.formatSingleProduct(returnedPurchaseProductEntity, isEdit);
    }

    /**
     * 关联新建格式化解释
     *
     * @param handlerExplainInLinkItemDTO 入参
     * @throws XbbException 异常
     */
    @Override
    public void formatLinkAddExplain(HandlerExplainInLinkItemDTO handlerExplainInLinkItemDTO) throws XbbException {
        Long linkDataId = handlerExplainInLinkItemDTO.getLinkDataId();
        List<FieldAttrEntity> explainList = handlerExplainInLinkItemDTO.getExplainList();
        PaasFormDataEntityExt paasFormDataEntityExt = handlerExplainInLinkItemDTO.getPaasFormDataEntityExt();
        FieldAttrEntity linkSupplierField = new FieldAttrEntity();
        FieldAttrEntity linkPurchaseField = new FieldAttrEntity();
        FieldAttrEntity linkProductField = new FieldAttrEntity();
        FieldAttrEntity moneyField = new FieldAttrEntity();
        for(FieldAttrEntity fieldAttrEntity :explainList) {
            if (Objects.equals(fieldAttrEntity.getAttr(), ReturnedPurchaseEnum.LINK_SUPPLIER.getAttr())) {
                linkSupplierField = fieldAttrEntity;
            }
            if (Objects.equals(fieldAttrEntity.getAttr(), ReturnedPurchaseEnum.PURCHASE_SHEET_ID.getAttr())) {
                linkPurchaseField = fieldAttrEntity;
            }
            if (Objects.equals(fieldAttrEntity.getAttr(), ReturnedPurchaseEnum.PRODUCTS.getAttr())) {
                linkProductField = fieldAttrEntity;
            }
            if (Objects.equals(fieldAttrEntity.getAttr(), ReturnedPurchaseEnum.TOTAL_MONEY.getAttr())) {
                moneyField = fieldAttrEntity;
            }
        }
        RedundantTemplateTypeEnum redundantTemplateTypeEnum = RedundantTemplateTypeEnum.getByCode(handlerExplainInLinkItemDTO.getLinkBusinessType());
        switch (redundantTemplateTypeEnum) {
            case PURCHASE:
                String purchaseNo = paasFormDataEntityExt.getSerialNo();
                linkPurchaseField.setDefaultAttr(saasUpdateHelp.getDefaultAttrPojo(linkDataId, purchaseNo));
                linkSupplierField.setDefaultAttr(saasUpdateHelp.getDefaultAttrPojo(FastJsonHelper.getJsonArrOrDefaultFromFormData(paasFormDataEntityExt.getData(), PurchaseEnum.SUPPLIER_ID.getAttr(), new JSONArray())));
                JSONObject productData= new JSONObject();
                List<BusinessProductEntity> businessProductEntityList = formDataValidateProductHelp.searchPurchaseUnRefund(handlerExplainInLinkItemDTO.getCorpid(),linkDataId);
                JSONArray jsonArray = new JSONArray();
                for (BusinessProductEntity entity : businessProductEntityList){
                    JSONObject json = new JSONObject();
                    json.put(ReturnPurchaseProductEnum.PRODUCT.getAttr(),entity.getProductId());
                    json.put(ReturnPurchaseProductEnum.NUM.getAttr(),entity.getProductNum());
                    json.put(ReturnPurchaseProductEnum.PURCHASE_PRICE.getAttr(),entity.getCost());
                    json.put(ReturnPurchaseProductEnum.UNIT.getAttr(),entity.getProductUnit());
                    json.put(ReturnPurchaseProductEnum.SUBTOTAL.getAttr(),entity.getProductNum() * entity.getCost());
                    if (Objects.nonNull(entity.getRefProductId())) {
                        json.put(BusinessConstant.REF_PRODUCT_ID, entity.getId());
                    }
                    json.put(BusinessConstant.PRODUCT_SUB_ID, 0);
                    jsonArray.add(json);
                }
                productData.put(PurchaseEnum.PRODUCT.getAttr(),jsonArray);
//                purchaseService.formatProduct4Show2(linkDataId,handlerExplainInLinkItemDTO.getCorpid(),productData, UpdateDataTypeEnum.LINK_ADD);
                JSONArray productArray = formDataValidateProductHelp.otherProductToAnother(productData,linkProductField,ReturnedPurchaseEnum.PRODUCTS.getAttr(),PurchaseEnum.PRODUCT.getAttr(),handlerExplainInLinkItemDTO.getCorpid(), handlerExplainInLinkItemDTO.getLoginUser(), handlerExplainInLinkItemDTO.getBusinessType(), handlerExplainInLinkItemDTO.getLinkBusinessType());
                //linkProductField.setDefaultAttr(saasUpdateHelp.setDefaultValue(productArray));
                Double totalProductMoney = 0D;
                for (int i = 0;i < productArray.size();i++){
                    JSONObject jsonObject = productArray.getJSONObject(i);
                    totalProductMoney += jsonObject.getDouble(ReturnPurchaseProductEnum.SUBTOTAL.getAttr());
                }
                DefaultAttrPoJo totalProductMoneyPojo = moneyField.getDefaultAttr();
                totalProductMoneyPojo.setUseLinkValue(BasicConstant.ONE);
                totalProductMoneyPojo.setLinkFormValue(totalProductMoney);
                moneyField.setDefaultAttr(totalProductMoneyPojo);
                break;
            default:
                break;
        }
    }


    /**
     * 将Excel数据格式化成表单保存需要的JSON格式的数据
     *
     * @param importFormDataDTO 导入入参
     * @param titlePojoList     标题
     * @param rowGroupPojo      一个表单对应的一组Excel填写的数据
     * @param fieldAttrList     解释
     * @return FormDataAddDTO
     * @throws XbbException XbbException
     * @author youli.chen
     * @date 2019/4/29 14:16
     * @since V1.0
     */
    @Override
    public FormDataAddDTO formatExcelValue(ImportFormDataDTO importFormDataDTO, List<CellTitlePojo> titlePojoList, RowGroupPojo rowGroupPojo, List<FieldAttrEntityForImport> fieldAttrList) throws XbbException {
        FormDataAddDTO formDataAddDTO = new FormDataAddDTO();
        BeanUtil.copyProperties(importFormDataDTO, formDataAddDTO);
        // data 数据
        JSONObject dataJson = new JSONObject();
        JSONObject productJson = new JSONObject();
        productJson.put(StringConstant.PRODUCT_LIST, new JSONArray());
        dataJson.put(ReturnedPurchaseEnum.PRODUCTS.getAttr(), productJson);

        List<List<CellValuePojo>> rowValueList = rowGroupPojo.getRowValueList();
        // 分组的第一条数据作为给实体对象赋值的数据
        List<CellValuePojo> cellValueList = rowValueList.get(0);
        String corpid = importFormDataDTO.getCorpid();
        for (FieldAttrEntityForImport item : fieldAttrList) {
            String attr = item.getAttr();
            Integer fieldType = item.getFieldType();
            String attrName = item.getAttrName();
            Integer columnIndex = importHelper.getColumnIndexByTitle(titlePojoList, attrName, null);
            Object cellValue = importHelper.getValueByColumnIndex(cellValueList, columnIndex);

            if (Objects.equals(attr, ReturnedPurchaseEnum.PRODUCTS.getAttr())) {
                // 获取产品array
                importHelper.formatCommonProduct(titlePojoList, dataJson, rowValueList, item, XbbRefTypeEnum.RETURNED_PURCHASE.getCode(), corpid);
            } else if (Objects.equals(fieldType, FieldTypeEnum.SUB_FORM.getType())) {
                importHelper.formatSubFormValue4Import(rowValueList, titlePojoList, importFormDataDTO, item, dataJson);
            } else if (Objects.equals(attr, ReturnedPurchaseEnum.PURCHASE_SHEET_ID.getAttr())) {
                importHelper.formatLinkBusinessValue4Import(dataJson, item, cellValue);
            } else if (Objects.equals(attr, ReturnedPurchaseEnum.MANAGER_ID.getAttr())) {
                importHelper.formatOwnId4Import(formDataAddDTO, item, cellValue);
            } else if (Objects.equals(fieldType, FieldTypeEnum.SERIALNO.getType())) {
                formDataAddDTO.setSerialNo(cellValue.toString());
            } else {
                if (Objects.isNull(cellValue) || StringUtil.isEmpty(cellValue.toString())) {
                    continue;
                }
                if (ImportHelper.commonHandleFieldType.contains(item.getFieldType())) {
                    importHelper.formatCommonField(dataJson, item, cellValue);
                } else if (Objects.equals(fieldType, FieldTypeEnum.LINK_DATA.getType())) {
                    importHelper.formatLinkData(cellValue, item, dataJson);
                } else if (Objects.equals(fieldType, FieldTypeEnum.LINK_DATA_MULTI.getType())) {
                    importHelper.formatLinkDataMulti(cellValue, importFormDataDTO, item, dataJson);
                } else {
                    dataJson.put(attr, cellValue);
                }
            }
        }
        formDataAddDTO.setDataList(dataJson);
        return formDataAddDTO;
    }

    /**
     * 格式化导出值
     *
     * @param paasFormDataESList 数据
     * @param formDataListDTO
     * @param fieldAttrList
     * @throws XbbException 异常
     */
    @Override
    public void formatExportValue(List<PaasFormDataEntityExt> paasFormDataESList, FormDataListDTO formDataListDTO, List<FieldAttrEntityForImport> fieldAttrList) throws XbbException {
        List<Long> businessIdIn = new ArrayList<>();
        List<Long> productIdIn = new ArrayList<>();
        paasFormDataESList.forEach(paasFormDataEntityExt -> businessIdIn.add(paasFormDataEntityExt.getId()));
        List<ReturnedPurchaseProductEntity> returnedPurchaseProductByReturnedPurchaseIdIn = returnedPurchaseProductModel.getReturnedPurchaseProductByReturnedPurchaseIdIn(formDataListDTO.getCorpid(), businessIdIn);
        Map<Long, List<ReturnedPurchaseProductEntity>> productMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        returnedPurchaseProductByReturnedPurchaseIdIn.forEach(returnedPurchaseProductEntity -> {
            List<ReturnedPurchaseProductEntity> productEntityList = new ArrayList<>();
            if (productMap.containsKey(returnedPurchaseProductEntity.getReturnPurchaseId())) {
                productEntityList.addAll(productMap.get(returnedPurchaseProductEntity.getReturnPurchaseId()));
            }
            productEntityList.add(returnedPurchaseProductEntity);
            productMap.put(returnedPurchaseProductEntity.getReturnPurchaseId(), productEntityList);
            productIdIn.add(returnedPurchaseProductEntity.getProductId());
        });
        List<ProductEntityExt> productList = productModel.getProductListByIdIn(formDataListDTO.getCorpid(), productIdIn, 0);
        Map<Long, ProductEntityExt> productsMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        productList.forEach(item -> productsMap.put(item.getId(), item));

        Map<String, MultiUnitItemPoJo> groupBaseUnitStringMap = relativeProductHelp.getGroupBaseUnitStringMap(formDataListDTO.getCorpid());

        for (PaasFormDataEntityExt paasFormDataEntityExt : paasFormDataESList) {
            JSONObject data = paasFormDataEntityExt.getData();
            List<ReturnedPurchaseProductEntity> singleReturnedPurchaseProductEntityList = productMap.getOrDefault(paasFormDataEntityExt.getId(), new ArrayList<>());
            for (FieldAttrEntityForImport fieldAttrEntityForImport : fieldAttrList) {
                if (Objects.equals(fieldAttrEntityForImport.getAttr(), ReturnedPurchaseEnum.PRODUCTS.getAttr())) {
                    JSONArray productArray = new JSONArray();
                    for (ReturnedPurchaseProductEntity entity : singleReturnedPurchaseProductEntityList) {
                        ProductEntityExt productEntityExt = productsMap.getOrDefault(entity.getProductId(), new ProductEntityExt());
                        JSONObject productData = productEntityExt.getData();
                        JSONObject productItemObj = entity.getData() == null ? new JSONObject() : entity.getData();
                        double rate = entity.getRate() == null ? 1 : entity.getRate();
                        String productSpecification = Objects.equals(entity.getProductSpecification(), "{}") ? "" : entity.getProductSpecification();
                        productItemObj.put(SelectProductEnum.PRODUCT_NAME.getAttr(), entity.getProductName());
                        productItemObj.put(SelectProductEnum.PRODUCT_NO.getAttr(), entity.getProductNo());
                        productItemObj.put(SelectProductEnum.BARCODE.getAttr(), productData.get(ProductEnum.BARCODE.getAttr()));
                        productItemObj.put(ReturnPurchaseProductEnum.NUM.getAttr(), Arith.div(entity.getProductNum(), rate));
                        productItemObj.put(ReturnPurchaseProductEnum.MEMO.getAttr(), entity.getMemo());
                        productItemObj.put(ReturnPurchaseProductEnum.PURCHASE_PRICE.getAttr(), Arith.div(entity.getProductPrice() ,rate));
                        // TODO 精度
                        productItemObj.put(ReturnPurchaseProductEnum.SUBTOTAL.getAttr(), Arith.mul(entity.getProductPrice(), entity.getProductNum()));
                        productItemObj.put(SelectProductEnum.SPECIFICATION.getAttr(), productSpecification);
                        productItemObj.put(SelectProductEnum.OUTSTOCK_NUM.getAttr(), entity.getOutstockNum());
                        productItemObj.put(SelectProductEnum.WAIT_OUTSTOCK_NUM.getAttr(), Arith.sub(entity.getProductNum(), entity.getOutstockNum()));
                        productItemObj.put(SelectProductEnum.UNIT.getAttr(), productData.get(ProductEnum.UNIT.getAttr()));
                        productItemObj.put(ProductEnum.ENABLE_MULTI_UNIT.getAttr(), productData.getIntValue(ProductEnum.ENABLE_MULTI_UNIT.getAttr()));
                        if (Objects.nonNull(productItemObj.get(SelectProductEnum.PRODUCE_DATE.getAttr()))) {
                            Long guaranteePeriod = productItemObj.getLong(SelectProductEnum.PRODUCE_DATE.getAttr());
                            String produceDateStr = DateTimeUtil.getStringEpochSecond(guaranteePeriod, DateTimeUtil.SDFDate);
                            productItemObj.put(SelectProductEnum.PRODUCE_DATE.getAttr(), produceDateStr);
                        }
                        //基本单位时直接塞入productUnit
                        if (Objects.isNull(entity.getBusinessUnit())){
                            if (Objects.equals(productItemObj.getInteger(ProductEnum.ENABLE_MULTI_UNIT.getAttr()), BasicConstant.ONE)){
                                productItemObj.put(ProductEnum.UNIT.getAttr(), groupBaseUnitStringMap.getOrDefault(productItemObj.getString(ProductEnum.UNIT.getAttr()), new MultiUnitItemPoJo()).getBaseValue());
                                entity.setProductUnit(productItemObj.getString(ProductEnum.UNIT.getAttr()));
                            }
                            productItemObj.put(SelectProductEnum.NUM.getAttr(), entity.getProductNum());
                        }else {
                            productItemObj.put(ProductEnum.UNIT.getAttr(), entity.getBusinessUnit());
                            productItemObj.put(SelectProductEnum.NUM.getAttr(), entity.getBusinessNum());
                            productItemObj.put(SelectProductEnum.OUTSTOCK_NUM.getAttr(), Arith.div(entity.getOutstockNum(), entity.getRate()));
                            productItemObj.put(SelectProductEnum.WAIT_OUTSTOCK_NUM.getAttr(), Arith.div(Arith.sub(entity.getProductNum(), entity.getOutstockNum()), entity.getRate()));
                        }
                        if (Objects.nonNull(entity.getPriceData()) && entity.getPriceData().size() > BasicConstant.ZERO){
                            productItemObj.put(ReturnPurchaseProductEnum.PURCHASE_PRICE.getAttr(), entity.getPriceData().get(ReturnPurchaseProductEnum.PURCHASE_PRICE.getAttr()));
                            productItemObj.put(ReturnPurchaseProductEnum.SUBTOTAL.getAttr(), Arith.mul(entity.getPriceData().getDouble(ProductEnum.PRICE.getAttr()), entity.getBusinessNum()));
                        }
                        if(Objects.equals(productItemObj.getInteger(ProductEnum.ENABLE_MULTI_UNIT.getAttr()), BasicConstant.ONE)){
                            productItemObj.put(SelectProductEnum.BASIC_UNIT.getAttr(), entity.getProductUnit());
                            productItemObj.put(SelectProductEnum.BASIC_UNIT_NUM.getAttr(),  entity.getProductNum());
                        }else {
                            productItemObj.put(SelectProductEnum.BASIC_UNIT.getAttr(), "");
                            productItemObj.put(SelectProductEnum.BASIC_UNIT_NUM.getAttr(), "");
                        }
                        productArray.add(productItemObj);
                    }
                    data.put(ReturnedPurchaseEnum.PRODUCTS.getAttr(), productArray);
                }
            }
        }
    }

    @Override
    public void updateBatchByBusinessRule(ReturnedPurchaseUpdateByBusinessRuleDTO returnedPurchaseUpdateByBusinessRuleDTO) throws XbbException {
        try {
            String corpid = returnedPurchaseUpdateByBusinessRuleDTO.getCorpid();
            List<PaasFormDataEntityExt> formDataList = returnedPurchaseUpdateByBusinessRuleDTO.getFormDataList();
            List<UpdateDataEntity> updateList = ExplainUtil.getUpdateValueByBusinessRule(returnedPurchaseUpdateByBusinessRuleDTO.getFormDataList(), corpid, returnedPurchaseUpdateByBusinessRuleDTO.getOperations());

            if (!updateList.isEmpty()) {
                returnedPurchaseModel.updateBatch(updateList, corpid);
                RuleBusinessLogDTO businessLogDTO = new RuleBusinessLogDTO();
                BeanUtil.copyProperties(returnedPurchaseUpdateByBusinessRuleDTO, businessLogDTO);
                businessLogDTO.setFormDataList(formDataList);
                ruleBusinessLogger.writeLog(businessLogDTO, updateList);
            }
        } catch (Exception e) {
            LOG.error("returnedPurchaseService.updateFormDataByBusinessRule根据业务规则更新数据出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }

    @Override
    public ProductSummaryVO summaryProductList(BusinessProductListDTO businessProductListDTO) throws XbbException {
        // 获取参数
        String corpid = businessProductListDTO.getCorpid();
        Long dataId = businessProductListDTO.getDataId();
        ReturnedPurchaseEntityExt returnedPurchaseEntityExt = returnedPurchaseModel.getByKey(dataId, corpid);

        Map<String, Object> modelMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        modelMap.put(ParameterConstant.CORPID, corpid);
        modelMap.put("returnPurchaseId", dataId);
        modelMap.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        modelMap.put("columns", "product_num,product_price,business_num");
        List<ReturnedPurchaseProductEntity> returnedPurchaseProductEntities = returnedPurchaseProductModel.findEntitys(modelMap);
        ProductSummaryVO businessProductListVO = new ProductSummaryVO();
        Double num = 0D;
        Double count = 0D;
        for (ReturnedPurchaseProductEntity productEntity : returnedPurchaseProductEntities) {
            Double productNum = productEntity.getProductNum() != null ? productEntity.getProductNum(): 0D;
            num = Arith.add(num, productEntity.getBusinessNum() == null ? productNum : productEntity.getBusinessNum());
            Double price = productEntity.getProductPrice() == null ? 0D : productEntity.getProductPrice();
            count = Arith.add(count, Arith.mul(productNum, price));
        }
        Integer productSize = returnedPurchaseProductEntities.size();
        String summaryInfo = String.format(I18nMessageUtil.getMessage(StringConstant.PRODUCTS_TYPE_NUM), productSize, Arith.doubleToBigDecimal(num));
        businessProductListVO.setSummaryInfo(summaryInfo);
        businessProductListVO.setMoneyInfo(String.format(I18nMessageUtil.getMessage(StringConstant.PRODUCTS_MONEY_COUNT), "", count));
        //添加关闭和开启合同的按钮
        JSONObject data = returnedPurchaseEntityExt.getData();
        String returnedStatus = FastJsonHelper.getStringOrDefaultFromFormData(data, ReturnedPurchaseEnum.RETURNED_STATUS.getAttr(), ReturnedStatusEnum.UNRETURNED.getCode());
        if (!Objects.equals(returnedStatus, ReturnedStatusEnum.RETURNED.getCode()) && num != 0D) {
            ButtonPojo buttonPojo = new ButtonPojo();
            if (Objects.equals(returnedStatus, ReturnedStatusEnum.CLOSED.getCode()) && businessProductListDTO.getLoginUser().getPermSet().contains(EnableButtonEnum.RETURN_PURCHASE_ENABLE.getPermission())) {
                buttonPojo.setAttr("returnPurchase");
                buttonPojo.setValue(OperateTypeEnum.ENABLE.getName());
                buttonPojo.setLinkBusinessType(XbbRefTypeEnum.RETURNED_PURCHASE.getCode());
                List<ButtonPojo> topRightButton = new ArrayList<>();
                topRightButton.add(buttonPojo);
                businessProductListVO.setTopRightButton(topRightButton);
            }else if (!Objects.equals(returnedStatus,ReturnedStatusEnum.CLOSED.getCode()) && businessProductListDTO.getLoginUser().getPermSet().contains(EnableButtonEnum.RETURN_PURCHASE_UNABLE.getPermission())){
                buttonPojo.setAttr("returnPurchase");
                buttonPojo.setValue(OperateTypeEnum.UNABLE.getName());
                buttonPojo.setLinkBusinessType(XbbRefTypeEnum.RETURNED_PURCHASE.getCode());
                List<ButtonPojo> topRightButton = new ArrayList<>();
                topRightButton.add(buttonPojo);
                businessProductListVO.setTopRightButton(topRightButton);
            }
        }
        return businessProductListVO;
    }

    @Override
    public void updateReturnedPurchaseInvoiceId(Long returnedPurchaseId, PaasFormDataEntity paasFormDataEntity, SaasFormSaveDTO saasFormSaveDTO) throws XbbException {
        String corpid = saasFormSaveDTO.getCorpid();
        ReturnedPurchaseUpdateBatchDTO returnedPurchaseUpdateBatchDTO = new ReturnedPurchaseUpdateBatchDTO();
        BeanUtil.copyProperties(saasFormSaveDTO, returnedPurchaseUpdateBatchDTO);
        List<ReturnedPurchaseUpdateDTO> returnedPurchaseUpdateList = new ArrayList<>();
        ReturnedPurchaseUpdateDTO returnedPurchaseUpdateDTO = new ReturnedPurchaseUpdateDTO();
        returnedPurchaseUpdateDTO.setId(returnedPurchaseId);
        JSONObject newData = new JSONObject();
        ReturnedPurchaseEntityExt returnedPurchaseEntityExt = returnedPurchaseModel.getByKey(returnedPurchaseId, corpid);
        JSONObject oldData = returnedPurchaseEntityExt.getData();
        JSONArray invoiceIds = FastJsonHelper.getJsonArrOrDefaultFromFormData(oldData, ReturnedPurchaseEnum.INVOICES.getAttr(), new JSONArray());
        invoiceIds.add(paasFormDataEntity.getId());
        newData.put(ReturnedPurchaseEnum.INVOICES.getAttr(), invoiceIds);
        JSONArray invoiceNames = FastJsonHelper.getJsonArrOrDefaultFromFormData(oldData, ReturnedPurchaseEnum.INVOICES_LINKED_TEXT.getAttr(), new JSONArray());
        invoiceNames.add(paasFormDataEntity.getSerialNo());
        newData.put(ReturnedPurchaseEnum.INVOICES_LINKED_TEXT.getAttr(), invoiceNames);
        returnedPurchaseUpdateDTO.setData(newData);
        returnedPurchaseUpdateList.add(returnedPurchaseUpdateDTO);
        returnedPurchaseUpdateBatchDTO.setReturnedPurchaseList(returnedPurchaseUpdateList);
        try{
            updateBatch(returnedPurchaseUpdateBatchDTO);
        } catch (XbbException e) {
            throw new XbbException(BuinessDefaultErrorCodeEnum.API_ERROR_200019);
        }
        long now = DateTimeUtil.getInt();
        //保存采购退货单发票关系表
        ReturnedPurchaseInvoiceEntity returnedPurchaseInvoiceEntity = new ReturnedPurchaseInvoiceEntity();
        returnedPurchaseInvoiceEntity.setReturnedPurchaseId(returnedPurchaseId);
        returnedPurchaseInvoiceEntity.setCorpid(corpid);
        returnedPurchaseInvoiceEntity.setDel(DelEnum.NORMAL.getDel());
        returnedPurchaseInvoiceEntity.setAddTime(now);
        returnedPurchaseInvoiceEntity.setUpdateTime(now);
        returnedPurchaseInvoiceEntity.setInvoiceId(paasFormDataEntity.getId());
        returnedPurchaseInvoiceModel.save(returnedPurchaseInvoiceEntity);

    }

    @Override
    public void updateRefund4Del(String corpid, List<Long> delIdList, Map<Long, Double> sheetIdToAmount) throws XbbException {
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
        boolQueryBuilder.filter(termsQuery(ReturnedPurchaseEnum.getEsAttr4Keyword(ReturnedPurchaseEnum.PAY_SHEETS), delIdList));
        boolQueryBuilder.filter(termQuery("del", 0));
        boolQueryBuilder.filter(termsQuery("flowStatus",Arrays.asList(FlowStatusEnum.NOT_NEED_APPROVAL.getType(), FlowStatusEnum.PASS.getType())));
        boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_RETURNED_PURCHASE.getType()));
        //字段过滤
        String refundAmountStr = StringConstant.JSON_DATA + StringConstant.POINT + ReturnedPurchaseEnum.RETURNED_PURCHASE_AMOUNT.getAttr();
        String refundPaymentSheetStr = StringConstant.JSON_DATA + StringConstant.POINT + ReturnedPurchaseEnum.PAY_SHEETS.getAttr();
        sourceBuilder.fetchSource(new String[]{StringConstant.SAAS_LINK_BUSINESS_ID, refundAmountStr, refundPaymentSheetStr}, null);
        sourceBuilder.query(boolQueryBuilder);
        SearchRequest searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_RETURNED_PURCHASE.getIndex());
        PageRequest pageRequest = EsUtil.setPage(sourceBuilder, BasicConstant.ONE, SizeConstant.PAGE_SIZE);
        searchRequest.source(sourceBuilder);
        XbbAggregatedPage<PaasFormDataEntityExt> esEntities = xbbElasticsearchRestTemplate.queryForPages(pageRequest, searchRequest, PaasFormDataEntityExt.class);
        List<PaasFormDataEntityExt> result = esEntities.getContent();
        if (result.size() > 0) {
            updateRefundAmountByIds(corpid, result, sheetIdToAmount);
        }
    }

    /**
     * 采购退货单 供应商名称一致性同步
     * @param corpid 公司ID
     * @param supplierId 供应商id
     * @param supplierName 供应商名称
     * @throws XbbException
     * @since v1.0
     * @version v1.0
     */
    @Override
    public void dataConsistencyUpdateSupplier(String corpid, Long supplierId, String supplierName) throws XbbException {
        try {
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put(ParameterConstant.CORPID, corpid);
            param.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
            param.put("supplierid", supplierId);
            List<ReturnedPurchaseEntityExt> entityExts = returnedPurchaseModel.getBySupplierId(param);
            //更新数据库的中的data的text_67供应商名称
            List<UpdateDataEntity> updateDataEntityList = new ArrayList<>();
            if(Objects.nonNull(entityExts)){
                for (ReturnedPurchaseEntityExt entityExt : entityExts) {
                    JSONObject data1 = entityExt.getData();
                    data1.put(ReturnedPurchaseEnum.LINK_SUPPLIER_HIDE.getAttr(),supplierName);
                    updateDataEntityList.add(ExplainUtil.getUpdateData(entityExt.getDataId(),data1, corpid));
                }
                returnedPurchaseModel.updateBatch(updateDataEntityList, corpid);
            }
        }catch (Exception e){
            LOG.error("ReturnPurchaseServiceImpl.dataConsistencyUpdateSupplier 出错，corpid=" + corpid + "  supplierId=" + supplierId + " supplierName=" + supplierName, e);
        }
    }

    /**
     * 获取采购退货合同产品
     *
     * @param businessProductListDTO 入参
     * @param dataList data对象
     * @author chaoxiong.lei
     * @Date 14:37 2019/3/5
     * @since v1.0
     * @return BusinessProductListVO，属性product包含了单据关联产品，返回给前端的格式
     **/
   /* @Override
    public BusinessProductListVO getReturnedPurchaseProductList(BusinessProductListDTO businessProductListDTO, JSONObject dataList) throws XbbException {
        // 获取参数
        String corpid = businessProductListDTO.getCorpid();
        Integer businessType = businessProductListDTO.getBusinessType();
        Integer sourceBusinessType = businessProductListDTO.getSourceBusinessType();
        Long returnedPurchaseId = businessProductListDTO.getDataId();
        boolean detailGet = businessProductListDTO.getDetailGet();
        ReturnedPurchaseEntityExt returnedPurchaseEntityExt;

        boolean isOutstock = Objects.equals(sourceBusinessType, XbbRefTypeEnum.OUTSTOCK.getCode());
        boolean generalGetProducts = !isOutstock;
        Map<String, Object> modelMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        modelMap.put(ParameterConstant.CORPID, corpid);
        modelMap.put("returnPurchaseId", returnedPurchaseId);
        modelMap.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        modelMap.put(ParameterConstant.PAGE, businessProductListDTO.getPage());
        PageHelper pageHelper = PageHelperUtil.getPageHelper(modelMap, returnedPurchaseProductModel, businessProductListDTO.getPageSize());
        // 采购退货单产品
        List<ReturnedPurchaseProductEntity> retPurchaseProducts = new ArrayList<>();
        if (businessProductListDTO.getForProcess()) {
            returnedPurchaseEntityExt = new ReturnedPurchaseEntityExt();
            JSONArray productArray = FastJsonHelper.getJsonArrOrDefaultFromFormData(saasUpdateHelp.getJsonObjectOrDefaultFromFormData(dataList, ReturnedPurchaseEnum.PRODUCTS.getAttr(), new JSONObject()), StringConstant.PRODUCT_LIST, new JSONArray());
            Map<Long, ProductEntityExt> productMap = getProductMap(corpid, productArray);
            getProductList(corpid, retPurchaseProducts, productArray, productMap);
        } else {
            retPurchaseProducts = (List<ReturnedPurchaseProductEntity>)PageHelperUtil.getEntityList(modelMap, pageHelper, returnedPurchaseProductModel);
            returnedPurchaseEntityExt = returnedPurchaseModel.getByKey(returnedPurchaseId, corpid);
            if (returnedPurchaseEntityExt == null) {
                throw new XbbException(ReturnedPurchaseErrorCodeEnum.API_ERROR_230001);
            }
        }

        Set<Long> productIds = new HashSet<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        productIds.add(-1L);
        retPurchaseProducts.forEach(item -> productIds.add(item.getProductId()));
        // 根据productIdIn获取对应产品信息
        Map<Long, PaasFormDataEntityExt> productMap = productService.getProductMapByIdIn( productIds, corpid,null);

        // 获取采购退货单对应的采购订单
        JSONObject retPurchaseDataList = returnedPurchaseEntityExt.getData();
        if (retPurchaseDataList == null) {
            retPurchaseDataList = dataList;
        }
        Long purchaseId = FastJsonHelper.getLongOrDefaultFromFormData(retPurchaseDataList, ReturnedPurchaseEnum.PURCHASE_SHEET_ID.getAttr(), 0L);
        // 获取采购合同对应产品的采购价信息
        Map<Long, Double> productCostMap = purchaseService.getReturnedProdCostMap(corpid, purchaseId);

        // 用于存放当前启用的产品模板解释的map
        // nowProductExplainMap中的key是saasAttr
        Map<String, FieldAttrEntity> nowProductExplainMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<String, FieldAttrEntity> nowStockProductExplainMap = null;
        if (isOutstock) {
            // 出库单选择采购退货单产品时，需要获取库存产品模板的自定义字段
            nowStockProductExplainMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        }
        saasAddHelp.getRelativeProductExplainsFromDB(corpid, nowProductExplainMap, nowStockProductExplainMap);

        // 返回给前端的接受对象
        JSONObject productFinalObj = new JSONObject();
        JSONArray productArray = new JSONArray();
        Map<Integer, JSONObject> productSortMap = new TreeMap<>();
        BusinessProductListVO businessProductListVO = new BusinessProductListVO();
        // 与productList同级，返回对应关联产品的attr
        String attrStr = "";
        boolean totalProductMoneyHide = false;

        if (isOutstock) {
            // 出库单选择采购退货产品
            attrStr = OutstockEnum.PRODUCT.getAttr();
            for (ReturnedPurchaseProductEntity returnedPurchaseProduct : retPurchaseProducts) {
                Long productId = returnedPurchaseProduct.getProductId();
                PaasFormDataEntityExt product = productMap.get(productId);
                if (product == null) {
                    continue;
                }
                JSONObject productDataList = product.getData();

                OutstockProductEntityExt outstockProduct = new OutstockProductEntityExt();
                BeanUtil.copyProperties(returnedPurchaseProduct, outstockProduct);
                outstockProduct.setBarcode(FastJsonHelper.getStringOrDefaultFromFormData(productDataList, ProductEnum.BARCODE.getAttr(), ""));

                // 设置备注
                ProductStockInfoEntity productStockInfoEntity = new ProductStockInfoEntity();
                String memo = returnedPurchaseProduct.getMemo();
                productStockInfoEntity.setMemo(memo);
                outstockProduct.setProductStockInfoEntity(productStockInfoEntity);

                // 获取采购合同关联产品的采购价作为采购退货出库的产品成本
                if(purchaseId > 0 && productCostMap.containsKey(productId)) {
                    // 采购退货订单有关联的采购订单，则以采购订单中产品的采购价为productCost
                    outstockProduct.setCost(productCostMap.get(productId));
                } else {
                    // 采购退货订单没有关联的采购订单，则以产品平均成本为productCost
                    // TODO 雷超雄 是产品平均成本还是tb_returned_purchase_product中的price?
                    outstockProduct.setCost(saasUpdateHelp.getDoubleOrDefaultFromFormData(productDataList, ProductEnum.COST.getAttr(), 0D));
                }
                JSONArray jsonArray = saasUpdateHelp.getJsonArrFromFormData(productDataList,ProductEnum.PRODUCT_IMGS.getAttr());
                outstockProduct.setImageUrlArray(jsonArray);
                // 构建格式化产品DTO
                FormatOutstockProductDTO formatOutstockProductDTO = new FormatOutstockProductDTO();
                BeanUtil.copyProperties(businessProductListDTO, formatOutstockProductDTO);
                formatOutstockProductDTO.setBusinessType(businessType);
                formatOutstockProductDTO.setOutstockProductExt(outstockProduct);
                formatOutstockProductDTO.setNowProductExplainMap(nowProductExplainMap);
                formatOutstockProductDTO.setNowStockProductExplainMap(nowStockProductExplainMap);

                JSONObject productObj = outstockService.getFormatProductJsonArray(formatOutstockProductDTO);
                productSortMap.put(returnedPurchaseProduct.getSort(), productObj);

                JSONArray array = productObj.getJSONArray(StringConstant.RESULT);
                boolean priceHide = false;
                for (Object obj : array) {
                    JSONObject productInfo = (JSONObject) obj;
                    if (Objects.equals(productInfo.get("attr"), "productPrice")) {
                        priceHide = productInfo.getBoolean("hidePrice");
                    }
                }

                if (priceHide) {
                    totalProductMoneyHide = true;
                }
            }
        }
        if (generalGetProducts) {
            List<String> unnecessaryAttrList = Arrays.asList(RelativeProductEnum.BATCH.getSaasAttr(), RelativeProductEnum.PRODUCE_DATE.getSaasAttr(), RelativeProductEnum.GUARANTEE_PERIOD.getSaasAttr());
            attrStr = ReturnedPurchaseEnum.PRODUCTS.getAttr();
            // 普通获取采购退货单产品（编辑+详情）
            double totalMoney = saasUpdateHelp.getDoubleOrDefaultFromFormData(retPurchaseDataList, ReturnedPurchaseEnum.TOTAL_MONEY.getAttr(), 0D);
            // 获取采购退货单解释
            Map<String, FieldAttrEntity> fieldAttrMap = paasFormExplainService.getFieldAttrMapByBusinessType(businessType, corpid);

            for (ReturnedPurchaseProductEntity returnedPurchaseProductEntity : retPurchaseProducts) {
                Long productId = returnedPurchaseProductEntity.getProductId();
                PaasFormDataEntityExt product = productMap.get(productId);
                if (product == null) {
                    continue;
                }
                JSONObject productDataList = product.getData();

                FormatRelativeProductEntityExt formatRelativeProduct = new FormatRelativeProductEntityExt();
                BeanUtil.copyProperties(returnedPurchaseProductEntity, formatRelativeProduct);
                formatRelativeProduct.setBarcode(FastJsonHelper.getStringOrDefaultFromFormData(productDataList, ProductEnum.BARCODE.getAttr(), ""));
                formatRelativeProduct.setProductName(FastJsonHelper.getStringOrDefaultFromFormData(productDataList, ProductEnum.NAME.getAttr(), ""));
                formatRelativeProduct.setStock(saasUpdateHelp.getDoubleOrDefaultFromFormData(productDataList, ProductEnum.STOCK.getAttr(), 0D));
                formatRelativeProduct.setCost(saasUpdateHelp.getDoubleOrDefaultFromFormData(productDataList, ProductEnum.COST.getAttr(), 0D));
                formatRelativeProduct.setProductUnit(FastJsonHelper.getStringOrDefaultFromFormData(productDataList, ProductEnum.UNIT.getAttr(), ""));
                formatRelativeProduct.setProductSpecification(FastJsonHelper.getStringOrDefaultFromFormData(productDataList, ProductEnum.SPECIFICATION_LINK_TEXT.getAttr(), ""));
                String imageUrl = "";
                JSONArray jsonArray = saasUpdateHelp.getJsonArrFromFormData(productDataList,ProductEnum.PRODUCT_IMGS.getAttr());
                if (Objects.nonNull(jsonArray) && !jsonArray.isEmpty()){
                    imageUrl = jsonArray.getString(jsonArray.size()-1);
                }
                formatRelativeProduct.setImageUrl(imageUrl);
                double num = returnedPurchaseProductEntity.getProductNum();
                double productPrice = returnedPurchaseProductEntity.getProductPrice();
                double subtotal = Arith.mul(num, productPrice);

                num = attrDecimalPrecisionHelper.setPrecision(num, nowProductExplainMap, ProductEnum.STOCK.getSaasAttr());
                subtotal = attrDecimalPrecisionHelper.setPrecision(subtotal, fieldAttrMap, ReturnedPurchaseEnum.TOTAL_MONEY.getAttr());

                formatRelativeProduct.setProductPrice(productPrice);
                formatRelativeProduct.setProductNum(num);
                String subTotalStr = attrDecimalPrecisionHelper.formatMoneyPrecision(subtotal, fieldAttrMap, ReturnedPurchaseEnum.TOTAL_MONEY.getAttr());
                formatRelativeProduct.setSubTotal(subtotal);
                formatRelativeProduct.setSubTotalStr(subTotalStr);

                // 构建格式化产品DTO
                FormatRelativeProductDTO formatRelativeProductDTO = new FormatRelativeProductDTO();
                BeanUtil.copyProperties(businessProductListDTO, formatRelativeProductDTO);
                formatRelativeProductDTO.setBusinessType(businessType);
                formatRelativeProductDTO.setTargetBusinessType(XbbRefTypeEnum.PURCHASE.getCode());

                formatRelativeProductDTO.setCorpid(corpid);
                formatRelativeProductDTO.setFormatRelativeProductEntityExt(formatRelativeProduct);
                formatRelativeProductDTO.setNowProductExplainMap(nowProductExplainMap);

                JSONObject productObj = productService.getFormatProductJsonArray(formatRelativeProductDTO);
                // 采购退货产品详情tab不显示批次等信息
                JSONArray productItemArray = productObj.getJSONArray(StringConstant.RESULT);
                productItemArray.removeIf(item -> unnecessaryAttrList.contains(((JSONObject) item).getString("attr")));
                productSortMap.put(returnedPurchaseProductEntity.getSort(), productObj);

                JSONArray array = productObj.getJSONArray(StringConstant.RESULT);
                boolean priceHide = false;
                for (Object obj : array) {
                    JSONObject productInfo = (JSONObject) obj;
                    if (Objects.equals(productInfo.get("attr"), "productPrice")) {
                        priceHide = productInfo.getBoolean("hidePrice");
                    }
                }

                if (priceHide) {
                    totalProductMoneyHide = true;
                }
            }
            // 详情页获取产品时需要返回解释
            if (detailGet) {
                // 采购退货产品详情tab不显示批次等信息
                List<FieldAttrEntityExt> fieldAttrEntityList = saasGetHelp.getSelectProductExplains(XbbRefTypeEnum.RETURNED_PURCHASE, businessProductListDTO.getBusinessType(), corpid, ReturnedPurchaseEnum.PRODUCTS.getAttr());
                fieldAttrEntityList.removeIf(item -> unnecessaryAttrList.contains(item.getAttr()));
                fieldAttrEntityList.forEach(item -> {
                    if (Objects.equals(item.getAttr(), RelativeProductEnum.PRODUCT_PRICE.getSaasAttr())) {
                        item.setAttrName(I18nMessageUtil.getMessage(I18nStringConstant.RETURN_UNIT_PRICE));
                    }
                });
                productFinalObj.put(BusinessConstant.EXPLAINS, fieldAttrEntityList);
            }
            JSONObject others = new JSONObject();
            String totalMoneyStr = totalProductMoneyHide ? StringConstant.INVISIBLE_VALUE : attrDecimalPrecisionHelper.formatMoneyPrecision(totalMoney, fieldAttrMap, ReturnedPurchaseEnum.TOTAL_MONEY.getAttr());
            others.put(BusinessConstant.TOTAL_PRODUCT_MONEY, totalMoneyStr);
            productFinalObj.put(BusinessConstant.OTHERS, others);
        }

        // 产品排序
        productArray.addAll(productSortMap.values());
        productFinalObj.put(StringConstant.PRODUCT_LIST, productArray);
        productFinalObj.put(StringConstant.REDUNDANT_FIELD_ATTR_BEGIN_FLAG, attrStr);
        businessProductListVO.setProduct(productFinalObj);
        businessProductListVO.setPageHelper(pageHelper);
        return businessProductListVO;
    }*/


    /**
     * 新建时格式化解释
     *
     * @param formatExplainDTO 入参
     * @throws XbbException 异常
     */
    @Override
    public void formatAddExplain(FormatExplainDTO formatExplainDTO) throws XbbException {
        List<FieldAttrEntity> explainList = formatExplainDTO.getExplainList();
        String corpid = formatExplainDTO.getCorpid();
        String platForm = formatExplainDTO.getPlatform();
        UserVO userVO = formatExplainDTO.getLoginUser();
        Set<String> permSet = userVO.getPermSet();
        for (FieldAttrEntity fieldAttrEntity : explainList) {
            Integer fieldType = fieldAttrEntity.getFieldType();
            String attr = fieldAttrEntity.getAttr();
            if (Objects.equals(fieldType, FieldTypeEnum.SELECT_PRODUCT.getType())) {
                explainHelp.formatSelectProductExplains(fieldAttrEntity, XbbRefTypeEnum.RETURNED_PURCHASE, corpid, OperatePageEnum.NEW.getCode(), false);
                if (Objects.equals(platForm, PlatFormEnum.DINGTALK.getValue())) {
                    SaasParticularAttributePoJo saasParticularAttributePoJo = fieldAttrEntity.getSaasParticularAttributePoJo();
                    saasParticularAttributePoJo.setProductRelyAttr(ReturnedPurchaseEnum.PURCHASE_SHEET_ID.getAttr());
                }
//                try {
//                    String outstockId = formatExplainDTO.getResult().getString(ReturnedPurchaseEnum.OUTSTOCK_ID.getAttr());
//                    if (StringUtil.isNotEmpty(outstockId) && !Objects.equals(outstockId, "0")) {
//                        fieldAttrEntity.setEditable(0);
//                    }
//                } catch (Exception e) {
//                    LOG.error("新建采购退货单格式化产品解释出错");
//                }
            }
            if (Objects.equals(attr, ReturnedPurchaseEnum.MANAGER_ID.getAttr())) {
                if(fieldAttrEntity.getDefaultAttr() == null || (fieldAttrEntity.getDefaultAttr() != null && fieldAttrEntity.getDefaultAttr().getDefaultList() == null)) {
                    fieldAttrEntity.setDefaultAttr(defaultAttrHelp.setUserDefaultAttrPoJo(formatExplainDTO.getUserId(), userVO.getName(), userVO.getAvatar()));
                }
            } else if (Objects.equals(attr, ReturnedPurchaseEnum.PAY_SHEETS.getAttr())) {
                //回款单新增权限判断
                if (!permSet.contains(ProPermissionAliasEnum.PAY_SHEET_ADD.getAlias())) {
                    fieldAttrEntity.setEditable(BasicConstant.ZERO);
                }
            } else if (Objects.equals(attr, ReturnedPurchaseEnum.INVOICES.getAttr())) {
                //红冲/作废发票按钮权限判断
                if (!permSet.contains(ProPermissionAliasEnum.PURCHASE_INVOICE_CANCEL.getAlias()) && !permSet.contains(ProPermissionAliasEnum.PURCHASE_INVOICE_RED.getAlias())) {
                    fieldAttrEntity.setEditable(BasicConstant.ZERO);
                }
            }
        }
    }

    /**
     * 对采购退货单产品进行相关校验
     *
     * @param returnedPurchaseProductList 采购退货产品数据
     * @param isNew                       是否新建
     * @param corpid                      公司ID
     * @param returnedPurchaseId          采购退货单ID
     * @date 2019/3/1 19:12
     * @author Jian.Wang
     */
    @Override
    public void checkReturnedPurchaseProduct(JSONObject returnedPurchaseProductList, boolean isNew, String corpid, Long returnedPurchaseId) throws XbbException {
        if (returnedPurchaseProductList.isEmpty()) {
            throw new XbbException(ReturnedPurchaseErrorCodeEnum.API_ERROR_230013);
        }
        // 获取采购退货产品数据
       // JSONObject returnedPurchaseProductJson = FastJsonHelper.getJsonObjectFromFormData(returnedPurchaseProductList, ReturnedPurchaseEnum.PRODUCTS.getAttr());
        JSONArray returnedPurchaseProductArray = returnedPurchaseProductList.getJSONArray(ReturnedPurchaseEnum.PRODUCTS.getAttr());
        for (Object object : returnedPurchaseProductArray) {
            JSONObject returnedPurchaseProduct = (JSONObject)object;
            if (!returnedPurchaseProduct.isEmpty()) {
                Double productNum = returnedPurchaseProduct.getDouble(RelativeProductEnum.NUM.getAttr());
                if (productNum < 0) {
                    throw new XbbException(PurchaseErrorCodeEnum.API_ERROR_225028);
                }
            }
        }
    }

    @Override
    public ReturnedPurchaseDeleteBatchVO deleteBatch(ReturnedPurchaseDeleteBatchDTO returnedPurchaseDeleteBatchDTO) throws XbbException {
        ReturnedPurchaseDeleteBatchVO returnedPurchaseDeleteBatchVO = new ReturnedPurchaseDeleteBatchVO();
        try {
            // TODO 删除权限校验
            // TODO 待审批或审批中的数据不能删
            List<Long> idIn = returnedPurchaseDeleteBatchDTO.getDataIdList();
            String corpid = returnedPurchaseDeleteBatchDTO.getCorpid();
            Map<String, Object> param = BeanUtil.convertBean2Map(returnedPurchaseDeleteBatchDTO, true);
            param.put("ids", idIn);
            param.put("del", DelEnum.NORMAL.getDel());
            List<ReturnedPurchaseEntityExt> returnedPurchaseList = returnedPurchaseModel.findEntitys(param);
            if (Objects.isNull(returnedPurchaseList)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }

            // 序列号关联表单删除校验
            if (CollectionUtils.isNotEmpty(idIn)) {
                productSerialService.preCheckDelSerial(idIn, corpid, XbbRefTypeEnum.RETURNED_PURCHASE.getCode());
            }
            Set<Long> purchaseSheetId = new HashSet<>();
            List<String> errorDataList = new ArrayList<>();
            List<String> errorTypeList = new ArrayList<>();
            //查询编号
            List<String> no= new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            Map<Long, Long> returnIdAndPurchaseId = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            for (ReturnedPurchaseEntityExt returnedPurchaseEntityExt : returnedPurchaseList) {
                JSONObject data = returnedPurchaseEntityExt.getData();
                returnIdAndPurchaseId.put(returnedPurchaseEntityExt.getId(), data.getLong(ReturnedPurchaseEnum.PURCHASE_SHEET_ID.getAttr()));
                String sheetNo = returnedPurchaseEntityExt.getSerialNo();
                no.add(sheetNo);
                if (Objects.nonNull(data) && Objects.nonNull(data.get(ReturnedPurchaseEnum.PURCHASE_SHEET_ID.getAttr()))) {
                    purchaseSheetId.add(data.getLong(ReturnedPurchaseEnum.PURCHASE_SHEET_ID.getAttr()));
                }
            }
            // 如果该采购退货单已生成【采购退货出库单】，则不允许删除
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            BoolQueryBuilder queryBuilder = boolQuery();
            queryBuilder.filter(termQuery("corpid.keyword",corpid));
            queryBuilder.filter(termsQuery("data." + OutstockEnum.REF_ID.getAttr(), idIn));
            queryBuilder.filter(termQuery("data." + OutstockEnum.TYPE.getAttr(), OutstockTypeEnum.RETURNED_PURCHASE_OUTSTOCK.getCode()));
            queryBuilder.filter(termQuery("del", 0));
            // 设置join_field
            queryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, IndexTypeEnum.IDX_SAAS_RETURNED_PURCHASE_OUTSTOCK.getType()));
            searchSourceBuilder.query(queryBuilder);
            List<String> fieldList = new ArrayList<>();
            fieldList.add(ReturnedPurchaseOutstockEnum.REF_ID.getAttr());
            List<PaasFormDataEntityExt> entityExts = paasEsModel.list(searchSourceBuilder, IndexTypeEnum.IDX_SAAS_RETURNED_PURCHASE_OUTSTOCK, fieldList, null, null);
//            if (Objects.nonNull(entityExts) && entityExts.size() > 0) {
//                throw new XbbException(ReturnedPurchaseErrorCodeEnum.API_ERROR_230019);
//            }
            // 生产了下游采购退货出库单的采购退货单id列表
            List<Long> returnedPurchaseIdList = new ArrayList<>();
            entityExts.forEach(entityExt -> {
                JSONObject extData = entityExt.getData();
                Long returnedPurchaseId = extData.getLong(ReturnedPurchaseOutstockEnum.REF_ID.getAttr());
                returnedPurchaseIdList.add(returnedPurchaseId);
            });
            List<String> returnedPurchases = new ArrayList<>();
            for (ReturnedPurchaseEntityExt returnedPurchaseEntityExt : returnedPurchaseList) {
                if (returnedPurchaseIdList.contains(returnedPurchaseEntityExt.getId())) {
                    returnedPurchases.add(returnedPurchaseEntityExt.getSerialNo());
                }
            }
            if (returnedPurchases.size() > 0) {
                throw new XbbException(ReturnedPurchaseErrorCodeEnum.API_ERROR_230019,String.format(ReturnedPurchaseErrorCodeEnum.API_ERROR_230019.getMsg(), returnedPurchases.toString()));
            }
            idIn.removeAll(returnedPurchaseIdList);
            if(!idIn.isEmpty()) {
                returnedPurchaseDeleteBatchVO.setDeleteIds(idIn);
                if(BasicConstant.ONE.equals(returnedPurchaseDeleteBatchDTO.getSingleFlag())
                        && BasicConstant.ONE.equals(idIn.size())){
                    returnedPurchaseModel.deleteByKey(idIn.get(0),corpid);
                }else {
                    // 删除采购退货单
                    returnedPurchaseModel.deleteBatch(idIn, corpid);
                }
                // 删除序列号
                productSerialService.deleteSerial(corpid, idIn, XbbRefTypeEnum.RETURNED_PURCHASE.getCode());
                returnedPurchaseInvoiceModel.deleteBatchByReturnedPurchaseIdIn(corpid, idIn);
            }
            ReturnedPurchaseProductDeleteBatchVO returnedPurchaseProductDeleteBatchVO = new ReturnedPurchaseProductDeleteBatchVO();
            if (idIn.size() > 0) {
                // 删除产品关联
                ReturnedPurchaseProductDeleteBatchDTO returnedPurchaseProductDeleteBatchDTO = new ReturnedPurchaseProductDeleteBatchDTO();
                BeanUtil.copyProperties(returnedPurchaseDeleteBatchDTO, returnedPurchaseProductDeleteBatchDTO);
                returnedPurchaseProductDeleteBatchDTO.setReturnedPurchaseIdIn(idIn);
                returnedPurchaseProductDeleteBatchVO = returnedPurchaseProductService.deleteBatch(returnedPurchaseProductDeleteBatchDTO);
            }
              // 重置采购合同退货单Id
            if (!purchaseSheetId.isEmpty()) {
                PurchaseUpdateBatchDTO purchaseUpdateBatchDTO = new PurchaseUpdateBatchDTO();
                BeanUtil.copyProperties(returnedPurchaseDeleteBatchDTO, purchaseUpdateBatchDTO);
                List<PurchaseUpdateDTO> purchaseList = new ArrayList<>();
                //删除采购退货单，无论新老数据，都置为0
                purchaseSheetId.forEach((item)->{
                    PurchaseUpdateDTO purchaseUpdateDTO = new PurchaseUpdateDTO();
                    purchaseUpdateDTO.setId(item);
                    JSONObject data = new JSONObject();
                    data.put(PurchaseEnum.RETURNED_PURCHASE_ID.getAttr(), 0);
                    purchaseUpdateDTO.setData(data);
                    purchaseList.add(purchaseUpdateDTO);
                });
                purchaseUpdateBatchDTO.setPurchaseList(purchaseList);
                purchaseService.updateBatch(purchaseUpdateBatchDTO);
            }
            //更新采购入库单产品的出库数量
            //更新采购合同产品的退货数量
            List<ReturnedPurchaseProductEntity> delList = returnedPurchaseProductDeleteBatchVO.getReturnedPurchaseProductList();
            List<ReturnedPurchaseProductEntity> newList = new ArrayList<>();
            List<ReturnedPurchaseProductEntity> oldList = new ArrayList<>();
            if (Objects.nonNull(delList)) {
                for(ReturnedPurchaseProductEntity del : delList){
                    if(Objects.isNull(del.getRefProductId())){
                        oldList.add(del);
                    }else {
                        newList.add(del);
                    }
                }
            }
            if (!CollectionUtils.isEmpty(newList)){
                //新数据才需要更新
                Map<Long,Double> numMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                Set<Long> instockIdList = new HashSet<>();
                for (ReturnedPurchaseProductEntity entity : newList){
                    Double num = numMap.getOrDefault(entity.getRefProductId(),0D);
                    num = Arith.add(num,entity.getProductNum());
                    numMap.put(entity.getRefProductId(),num);
                    instockIdList.add(entity.getRefProductId());
                }
                param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put("corpid",corpid);
                param.put("idIn",new ArrayList<>(instockIdList));
                param.put("del",0);
                List<InstockProductEntity> instockProductEntityList = instockProductModel.findEntitys(param);
                Map<Long,Double> purchaseMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                HashSet<Long> refInProductIds = new HashSet<>();
                for (InstockProductEntity entity : instockProductEntityList){
                    Long id = entity.getId();
                    Double num = numMap.getOrDefault(id,0D);
                    Double outstockNum = Objects.isNull(entity.getOutstockNum()) ? 0D : entity.getOutstockNum();
                    outstockNum = Arith.sub(outstockNum,num);
                    if (outstockNum < 0D){
                        outstockNum = 0D;
                    }
                    entity.setOutstockNum(outstockNum);
                    Long refProductId = entity.getRefProductId();
                    //采购入库单产品的refProductId不为空的，才更新采购合同产品的退货数量
                    if (Objects.nonNull(refProductId)){
                        Double returnNum = purchaseMap.getOrDefault(refProductId,0D);
                        returnNum = Arith.add(returnNum,num);
                        purchaseMap.put(refProductId,returnNum);
                    }else {
                        refInProductIds.add(id);
                    }
                }
                if (!instockProductEntityList.isEmpty()){
                    instockProductModel.updateBatch(instockProductEntityList,corpid);
                }

                if (!purchaseMap.isEmpty()){
                    //新数据才需要更新
                    param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    param.put("corpid",corpid);
                    param.put("idIn",new ArrayList<>(purchaseMap.keySet()));
                    param.put("del",0);
                    List<PurchaseProductEntity> purchaseProductEntityList = purchaseProductModel.findEntitys(param);
                    for (PurchaseProductEntity entity : purchaseProductEntityList){
                        Long id = entity.getId();
                        Double num = purchaseMap.getOrDefault(id,0D);
                        Double outstockNum = Objects.isNull(entity.getOutstockNum()) ? 0D : entity.getOutstockNum();
                        outstockNum = Arith.sub(outstockNum,num);
                        if (outstockNum < 0D){
                            outstockNum = 0D;
                        }
                        entity.setOutstockNum(outstockNum);
                    }
                    if (!purchaseProductEntityList.isEmpty()){
                        purchaseProductModel.updateBatch(purchaseProductEntityList,corpid);
                    }
                }
 //                    采购退货是新数据，入库单是老数据的情况
                if (!refInProductIds.isEmpty()) {
                    Map<Object, Double> returnProductNumsMap = new HashMap<>();
                    HashSet<Long> purchaseIds = new HashSet<>();
                    for (ReturnedPurchaseProductEntity entity : newList) {
                        if (refInProductIds.contains(entity.getRefProductId())) {
                            Long purchaseId = returnIdAndPurchaseId.getOrDefault(entity.getReturnPurchaseId(), 0L);
                            purchaseIds.add(purchaseId);
                            String key = purchaseId + "" + entity.getProductId();
                            Double num = returnProductNumsMap.getOrDefault(key, 0D);
                            num += entity.getProductNum();
                            returnProductNumsMap.put(key, num);
                        }
                    }
                    param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    param.put("corpid",corpid);
                    param.put("purchaseIdIn", purchaseIds);
                    param.put("del",0);
                    List<PurchaseProductEntity> purchaseProductEntityList = purchaseProductModel.findEntitys(param);
                    for (PurchaseProductEntity entity : purchaseProductEntityList) {
                        String key = entity.getPurchaseSheetId() + "" + entity.getProductId();
                        Double amendNum =  returnProductNumsMap.getOrDefault(key, 0D);
                        Double outstockNum ;
                        if (Arith.sub(entity.getOutstockNum(), amendNum) > 0){
                            outstockNum = Arith.sub(entity.getOutstockNum(), amendNum);
                            returnProductNumsMap.remove(key);
                        }else {
                            outstockNum = 0D;
                            returnProductNumsMap.put(key, Arith.sub(entity.getOutstockNum(), amendNum));
                        }
                        entity.setOutstockNum(outstockNum);
                    }
                    if (!purchaseProductEntityList.isEmpty()){
                        purchaseProductModel.updateBatch(purchaseProductEntityList,corpid);
                    }
                }

            }
            if (!oldList.isEmpty()) {
//                      采购退货是老数据，入库单是老数据的情况
                HashSet<Long> allOldPurchaseIds = new HashSet<>();
                Map<Object, Double> returnProductNumsMap = new HashMap<>();
                for (ReturnedPurchaseProductEntity entity : oldList) {
                    Long purchaseId = returnIdAndPurchaseId.getOrDefault(entity.getReturnPurchaseId(), 0L);
                    allOldPurchaseIds.add(purchaseId);
                    String key = purchaseId + "" + entity.getProductId();
                    Double num = returnProductNumsMap.getOrDefault(key, 0D);
                    num += entity.getProductNum();
                    returnProductNumsMap.put(key, num);
                }
                param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put("corpid",corpid);
                param.put("purchaseIdIn", allOldPurchaseIds);
                param.put("del",0);
                List<PurchaseProductEntity> purchaseProductEntityList = purchaseProductModel.findEntitys(param);
                for (PurchaseProductEntity entity : purchaseProductEntityList) {
                    String key = entity.getPurchaseSheetId() + "" + entity.getProductId();
                    Double amendNum =  returnProductNumsMap.getOrDefault(key, 0D);
                    Double outstockNum ;
                    if (Arith.sub(entity.getOutstockNum(), amendNum) > 0){
                        outstockNum = Arith.sub(entity.getOutstockNum(), amendNum);
                        returnProductNumsMap.remove(key);
                    }else {
                        outstockNum = 0D;
                        returnProductNumsMap.put(key, Arith.sub(entity.getOutstockNum(), amendNum));
                    }
                    entity.setOutstockNum(outstockNum);
                }
                if (!purchaseProductEntityList.isEmpty()){
                    purchaseProductModel.updateBatch(purchaseProductEntityList,corpid);
                }
            }

            // TODO 删除关联审批记录

            returnedPurchaseDeleteBatchVO.setErrorDataList(errorDataList);
            returnedPurchaseDeleteBatchVO.setErrorTypeList(errorTypeList);
            returnedPurchaseDeleteBatchVO.setErrorDataMemo(SaasDeleteHelp.getErrorDataMemo(errorTypeList, errorDataList));

            OperateTypeEnum operateTypeEnum = OperateTypeEnum.DELETE;
            if (Objects.equals(1, returnedPurchaseDeleteBatchDTO.getIsBusinessRule())) {
                operateTypeEnum = OperateTypeEnum.RULE_DELETE;
            }
            //生成删除日志(区分单个删除和批量删除)
            String userId = returnedPurchaseDeleteBatchDTO.getUserId();
            String userName = returnedPurchaseDeleteBatchDTO.getLoginUserName();
            String nameStr = StringUtils.join(no, "，");
            if(idIn.size() > 1){
                String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_BATCH_DELETE_FORM_DETAIL), userName, XbbRefTypeEnum.RETURNED_PURCHASE.getName(), idIn.size());
                List<InfoArrPojo> infoArrPojoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                InfoArrPojo infoArrPojo = new InfoArrPojo();
                infoArrPojo.setTitle(ReturnedPurchaseEnum.SHEET_NO.getAttrName());
                infoArrPojo.setContent(nameStr);
                infoArrPojoList.add(infoArrPojo);
                mongoLogHelp.buildLog4InfoArr(infoArrPojoList, corpid, userId, userName, OperateModuleTypeEnum.RETURN_PURCHASE, operateTypeEnum,
                        "", "", memo, returnedPurchaseDeleteBatchDTO.getHttpHeader());
            } else if (Objects.equals(idIn.size(), 1)){
                String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_DELETE_WORK), userName, XbbRefTypeEnum.RETURNED_PURCHASE.getName(), nameStr);
                mongoLogHelp.buildLog(corpid, userId, userName, OperateModuleTypeEnum.RETURN_PURCHASE, operateTypeEnum,
                        idIn.get(0).toString(), nameStr, memo, returnedPurchaseDeleteBatchDTO.getHttpHeader());
            }

        }catch (XbbException e){
            throw e;
        }catch (Exception e) {
            LOG.error("returnedPurchaseServiceImpl.deleteBatch 执行出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return returnedPurchaseDeleteBatchVO;
    }

    @Override
    public ReturnedPurchaseUpdateBatchVO updateBatch(ReturnedPurchaseUpdateBatchDTO returnedPurchaseUpdateBatchDTO) throws XbbException {
        ReturnedPurchaseUpdateBatchVO returnedPurchaseUpdateBatchVO = new ReturnedPurchaseUpdateBatchVO();
        try {
            String corpid = returnedPurchaseUpdateBatchDTO.getCorpid();
            List<UpdateDataEntity> updateList = new ArrayList<>();
            List<ReturnedPurchaseUpdateDTO> returnedPurchaseList = returnedPurchaseUpdateBatchDTO.getReturnedPurchaseList();
            if (Objects.nonNull(returnedPurchaseList) && !returnedPurchaseList.isEmpty()) {
                returnedPurchaseList.forEach((item)->{
                    updateList.add(ExplainUtil.getUpdateData(item.getId(), item.getData(), corpid));
                });
            }
            if (!updateList.isEmpty()) {
                returnedPurchaseModel.updateBatch(updateList, corpid);
            }

        } catch (Exception e) {
            LOG.error("returnedPurchaseServiceImpl.updateBatch 执行出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return returnedPurchaseUpdateBatchVO;
    }

    @Override
    public ReturnedPurchaseUpdateBatchVO update(ReturnedPurchaseUpdateBatchDTO returnedPurchaseUpdateBatchDTO) throws XbbException {
        ReturnedPurchaseUpdateBatchVO returnedPurchaseUpdateBatchVO = new ReturnedPurchaseUpdateBatchVO();
        try {
            String corpid = returnedPurchaseUpdateBatchDTO.getCorpid();
            List<UpdateDataEntity> updateList = new ArrayList<>();
            List<ReturnedPurchaseUpdateDTO> returnedPurchaseList = returnedPurchaseUpdateBatchDTO.getReturnedPurchaseList();
            if (Objects.nonNull(returnedPurchaseList) && !returnedPurchaseList.isEmpty()) {
                returnedPurchaseList.forEach((item)->{
                    updateList.add(ExplainUtil.getUpdateData(item.getId(), item.getData(), corpid));
                });
            }
            if (!updateList.isEmpty()) {
                returnedPurchaseModel.update(updateList, corpid);
            }

        } catch (Exception e) {
            LOG.error("returnedPurchaseServiceImpl.updateBatch 执行出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return returnedPurchaseUpdateBatchVO;
    }

    @Override
    public void batchEditAttr(ReturnedPurchaseEditAttrUpdateDTO returnedPurchaseEditAttrUpdateDTO) throws XbbException {
        try {
            List<ReturnedPurchaseUpdateDTO> returnedPurchaseList = new ArrayList<>();
            returnedPurchaseEditAttrUpdateDTO.getDataIdList().forEach((item)->{
                ReturnedPurchaseUpdateDTO returnedPurchaseUpdateDTO = new ReturnedPurchaseUpdateDTO();
                returnedPurchaseUpdateDTO.setId(item);
                JSONObject data = ProSaveHelp.getBatchUpdateData(returnedPurchaseEditAttrUpdateDTO.getFieldEditedList());
                returnedPurchaseUpdateDTO.setData(data);
                returnedPurchaseList.add(returnedPurchaseUpdateDTO);
            });
            List<ReturnedPurchaseEntityExt> returnPurchaseEntityList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            if (!returnedPurchaseList.isEmpty()) {
                Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put("corpid", returnedPurchaseEditAttrUpdateDTO.getCorpid());
                param.put("idIn", returnedPurchaseEditAttrUpdateDTO.getDataIdList());
                returnPurchaseEntityList = returnedPurchaseModel.findEntitys(param);
                if (Objects.isNull(returnPurchaseEntityList)){
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
                }
                //权限团队校验前置了
                List<Long> errorIdList = new ArrayList<>();
//                List<Long> errorIdList = userTeamHelp.batchTeamMembersCheckEditPermission(returnedPurchaseEditAttrUpdateDTO.getBusinessType(), returnedPurchaseEditAttrUpdateDTO.getSaasMark(),
//                        returnedPurchaseEditAttrUpdateDTO.getMenuId(), returnedPurchaseEditAttrUpdateDTO.getLoginUser(), returnedPurchaseEditAttrUpdateDTO.getDistributorMark(),
//                        returnedPurchaseEditAttrUpdateDTO.getDataIdList(), new HashMap<>());
                List<String> errorNameList = new ArrayList<>();
                for (ReturnedPurchaseEntityExt returnedPurchaseEntityExt : returnPurchaseEntityList) {
                    if (errorIdList.contains(returnedPurchaseEntityExt.getId())) {
                        errorNameList.add(returnedPurchaseEntityExt.getData().getString(ReturnedPurchaseEnum.SHEET_NO.getAttr()));
                    }
                }
                String nameStr = org.apache.commons.lang.StringUtils.join(errorNameList, "、");
                if (CollectionUtils.isNotEmpty(errorNameList)) {
                    throw new XbbException(UserTeamErrorCodeEnum.API_ERROR_271038.getCode(), String.format(UserTeamErrorCodeEnum.API_ERROR_271038.getMsg(), nameStr));
                }
                ReturnedPurchaseUpdateBatchDTO returnedPurchaseUpdateBatchDTO = new ReturnedPurchaseUpdateBatchDTO();
                BeanUtil.copyProperties(returnedPurchaseEditAttrUpdateDTO, returnedPurchaseUpdateBatchDTO);
                returnedPurchaseUpdateBatchDTO.setReturnedPurchaseList(returnedPurchaseList);
                updateBatch(returnedPurchaseUpdateBatchDTO);
            }

            // 批量编辑日志
            List<String> updataItemList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            List<Long> dataIdList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            for (ReturnedPurchaseEntityExt item : returnPurchaseEntityList) {
                dataIdList.add(item.getId());
                String serialNo = item.getSerialNo();
                updataItemList.add(serialNo);
            }
            String updataItem = StringUtils.join(updataItemList, "，");
            String userId = returnedPurchaseEditAttrUpdateDTO.getUserId();
            String corpid = returnedPurchaseEditAttrUpdateDTO.getCorpid();
            String loginUserName = returnedPurchaseEditAttrUpdateDTO.getLoginUserName();
            // 标签特殊处理
            Integer fieldType = returnedPurchaseEditAttrUpdateDTO.getFieldType();
            Boolean isFieldDependence = returnedPurchaseEditAttrUpdateDTO.getIsFieldDependence();
            logHelp.analysisLabel(corpid, fieldType, isFieldDependence,returnedPurchaseEditAttrUpdateDTO.getLogFieldEditedList());

            String changedLogItemsStr = logHandleHelp.getChangedLogItemsStr(returnedPurchaseEditAttrUpdateDTO.getLogFieldEditedList());
            if(dataIdList.size() > 1 ){
                String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_UPDATE_FORM_DATA_BATCH_ATTR), loginUserName, XbbRefTypeEnum.RETURNED_PURCHASE.getName(),
                        changedLogItemsStr, dataIdList.size());
                List<InfoArrPojo> infoArrPojoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                InfoArrPojo infoArrPojo = new InfoArrPojo();
                infoArrPojo.setTitle(XbbRefTypeEnum.RETURNED_PURCHASE.getName());
                infoArrPojo.setContent(updataItem);
                infoArrPojoList.add(infoArrPojo);
                mongoLogHelp.buildLog4InfoArr(infoArrPojoList, corpid, userId, loginUserName, OperateModuleTypeEnum.RETURN_PURCHASE, OperateTypeEnum.EDIT,
                        "", "", memo, returnedPurchaseEditAttrUpdateDTO.getHttpHeader());
            } else if (Objects.equals(dataIdList.size(), 1)){
                String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_UPDATE_FORM_DATA_ATTR), loginUserName, XbbRefTypeEnum.RETURNED_PURCHASE.getName(), updataItem,
                        changedLogItemsStr);
                mongoLogHelp.buildLog(corpid, userId, loginUserName, OperateModuleTypeEnum.RETURN_PURCHASE, OperateTypeEnum.EDIT,
                        dataIdList.get(0).toString(), updataItem, memo, returnedPurchaseEditAttrUpdateDTO.getHttpHeader());
            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("returnedPurchaseService.batchEditAttr 执行出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }

    @Override
    public boolean judgeReturnPurchaseAllOutBound(Long outstockId, Long contractId, String corpid, List<ProductSavePojo> productSavePojoList) throws XbbException {
        return returnedPurchaseHelp.judgeReturnPurchaseAllOutBound(outstockId, contractId, corpid, productSavePojoList);
    }

    @Override
    public ChangeDocumentStatusSaveVO changeDocumentStatus(ChangeDocumentStatusSaveDTO changeDocumentStatusSaveDTO) throws XbbException {
        ChangeDocumentStatusSaveVO changeDocumentStatusSaveVO = new ChangeDocumentStatusSaveVO();
        try {
            Boolean isOpen = changeDocumentStatusSaveDTO.getIsOpen();
            String corpid = changeDocumentStatusSaveDTO.getCorpid();
            Long returnedPurchaseId = changeDocumentStatusSaveDTO.getDataId();
            Integer businessType = changeDocumentStatusSaveDTO.getBusinessType();
            ReturnedPurchaseEntityExt returnedPurchaseEntityExt = returnedPurchaseModel.getByKey(returnedPurchaseId, corpid);
            if (Objects.isNull(returnedPurchaseEntityExt)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100028, MessageConstant.FORM_DATA_NOT_EXIST);
            }
            JSONObject returnedPurchaseData = returnedPurchaseEntityExt.getData();
            //如果是开启采购退款
            if (isOpen) {
                Integer outstockId = getIntegerOrDefaultFromFormData(returnedPurchaseData,ReturnedPurchaseEnum.OUTSTOCK_ID.getAttr(),0);
                //大于0代表出库完毕
                if (outstockId>0) {
                    returnedPurchaseData.put(ReturnedPurchaseEnum.RETURNED_STATUS.getAttr(), ReturnedStatusEnum.RETURNED.getCode());
                }else {
                    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
                    BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
                    boolQueryBuilder.filter(termQuery("corpid.keyword",corpid));
                    boolQueryBuilder.filter(termQuery(OutstockEnum.getEsAttr4Keyword(OutstockEnum.TYPE), OutstockTypeEnum.RETURNED_PURCHASE_OUTSTOCK.getCode()));
                    boolQueryBuilder.filter(termQuery(OutstockEnum.getEsAttr4Keyword(OutstockEnum.REF_ID), returnedPurchaseId));
                    boolQueryBuilder.filter(termQuery(StringConstant.DEL,DelEnum.NORMAL.getDel()));
                    boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, IndexTypeEnum.IDX_SAAS_OUTSTOCK.getType()));
                    sourceBuilder.query(boolQueryBuilder);
                    PageRequest pageRequest = EsUtil.setPage(sourceBuilder, 1, 1);
                    SearchRequest searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_OUTSTOCK.getIndex());
                    searchRequest.source(sourceBuilder);
                    XbbAggregatedPage<PaasFormDataEntityExt> entities = xbbElasticsearchRestTemplate.queryForPages(pageRequest,searchRequest, PaasFormDataEntityExt.class);

                    if (entities.getTotalElements() < 1){
                        returnedPurchaseData.put(ReturnedPurchaseEnum.RETURNED_STATUS.getAttr(), ReturnedStatusEnum.UNRETURNED.getCode());
                    }else {
                        returnedPurchaseData.put(ReturnedPurchaseEnum.RETURNED_STATUS.getAttr(), ReturnedStatusEnum.DELIVERED.getCode());
                    }
                }
            }else {
                returnedPurchaseData.put(ReturnedPurchaseEnum.RETURNED_STATUS.getAttr(), ReturnedStatusEnum.CLOSED.getCode());
            }
            returnedPurchaseModel.update(returnedPurchaseEntityExt);
            //添加关闭和开启采购退货的按钮
            String returnedStatus = FastJsonHelper.getStringOrDefaultFromFormData(returnedPurchaseData, ReturnedPurchaseEnum.RETURNED_STATUS.getAttr(), ReturnedStatusEnum.UNRETURNED.getCode());
            //如果全部出库，则没有开启关闭按钮
            if (!Objects.equals(returnedStatus, ReturnedStatusEnum.RETURNED.getCode())) {
                ButtonPojo buttonPojo = new ButtonPojo();
                if (Objects.equals(returnedStatus,ReturnedStatusEnum.CLOSED.getCode())&&changeDocumentStatusSaveDTO.getLoginUser().getPermSet().contains(EnableButtonEnum.RETURN_PURCHASE_ENABLE.getPermission())) {
                    buttonPojo.setAttr("returnPurchase");
                    buttonPojo.setValue(OperateTypeEnum.ENABLE.getName());
                    buttonPojo.setLinkBusinessType(XbbRefTypeEnum.RETURNED_PURCHASE.getCode());
                    List<ButtonPojo> topRightButton = new ArrayList<>();
                    topRightButton.add(buttonPojo);
                    changeDocumentStatusSaveVO.setTopRightButton(topRightButton);
                }else if (!Objects.equals(returnedStatus,RefundStatusEnum.CLOSED.getCode())&&changeDocumentStatusSaveDTO.getLoginUser().getPermSet().contains(EnableButtonEnum.RETURN_PURCHASE_UNABLE.getPermission())){
                    buttonPojo.setAttr("returnPurchase");
                    buttonPojo.setValue(OperateTypeEnum.UNABLE.getName());
                    buttonPojo.setLinkBusinessType(XbbRefTypeEnum.RETURNED_PURCHASE.getCode());
                    List<ButtonPojo> topRightButton = new ArrayList<>();
                    topRightButton.add(buttonPojo);
                    changeDocumentStatusSaveVO.setTopRightButton(topRightButton);
                }
            }
            // 刷新页面saas关联新建工作流
            PaasFormDataEntityExt paasFormDataEntityExt = new PaasFormDataEntityExt();
            BeanUtil.copyProperties(returnedPurchaseEntityExt,paasFormDataEntityExt);
            if (Objects.equals(PlatFormEnum.DINGTALK.getValue(), changeDocumentStatusSaveDTO.getPlatform())) {
                // 设置移动端详情右上角操作
                FormDataGetVO formDataGetVO = new FormDataGetVO();
                mobileDetailService.handelMobileWorkFlow(changeDocumentStatusSaveDTO.getLoginUser(), businessType, formDataGetVO, paasFormDataEntityExt);
                changeDocumentStatusSaveVO.setTopPermissions(formDataGetVO.getTopPermissions());
            }else {
                List<WorkFlowPojo> workFlowPojoList = new ArrayList<>();
                proDetailHandlerHelp.handelDetailWorkFlow(businessType, paasFormDataEntityExt, workFlowPojoList, changeDocumentStatusSaveDTO.getLoginUser());
                changeDocumentStatusSaveVO.setWorkFlowPojoList(workFlowPojoList);
            }
        } catch (Exception e) {
            LOG.error("returnedPurchaseServiceImpl.changeDocumentStatus 执行出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return changeDocumentStatusSaveVO;
    }



    /**
     * 生成红冲付款单
     *
     * @param paySheetArray 选择关联的付款单
     * @param saasFormSaveDTO   保存入参
     * @throws XbbException 异常
     */
    private List<Long> generateRedPay(JSONArray paySheetArray, SaasFormSaveDTO saasFormSaveDTO) throws XbbException {
        List<Long> redPaySheetIds = new ArrayList<>();
        JSONObject newData = saasFormSaveDTO.getNewData();
        if (paySheetArray == null || paySheetArray.isEmpty() || newData == null) {
            return redPaySheetIds;
        }
        //是否设置红冲付款单的id,老审批应该为true,工作流公司回款单如果开了工作流审批 应该为false,其他情况均为true
        boolean isSetPaymentFlag = true;
        String corpid = saasFormSaveDTO.getCorpid();
        if (commonHelp.isOpenWorkFlow(corpid)) {
            Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            params.put("del", 0);
            params.put("businessType", XbbRefTypeEnum.PAY_SHEET.getCode());
            params.put("corpid", corpid);
            List<PaasFormEntityExt> paasFormEntityExts = paasFormModel.findEntitys(params);
            Long paySheetFormId = CollectionsUtil.isNotEmpty(paasFormEntityExts) ? paasFormEntityExts.get(BasicConstant.ZERO).getId() : 0L;
            List<WorkflowEntity> list = workflowFormDataOperationService.getSatisfyTriggerEntitys(corpid,
                    paySheetFormId, XbbRefTypeEnum.PAY_SHEET.getCode(), Arrays.asList(TriggerEventTypeEnum.ONLY_ADD.getType(), TriggerEventTypeEnum.ADD_OR_UPDATE.getType()));
            isSetPaymentFlag = !(CollectionsUtil.isNotEmpty(list) && list.stream().map(WorkflowEntity::getEnable).collect(Collectors.toList()).contains(BasicConstant.ONE));
        }
        // 采购退货关联的回款单
        for(Object obj : paySheetArray) {
            JSONObject payJsonObject = (JSONObject) obj;
            PayPlanSheetEntityExt payPlanSheetEntityExt;
            payPlanSheetEntityExt = handlePaySheetWebPlatformLinkAddData(payJsonObject);
            FormDataAddDTO formDataAddDTO = new FormDataAddDTO();
            BeanUtil.copyProperties(payPlanSheetEntityExt, formDataAddDTO);
            BeanUtil.copyProperties(saasFormSaveDTO, formDataAddDTO);
            JSONObject dataList = payPlanSheetEntityExt.getData();
            dataList.remove(PaySheetEnum.INVOICE_AMOUNT.getAttr());
            JSONObject paySheetTypeObj = FastJsonHelper.getJsonObjectOrDefaultFromFormData(dataList, PaySheetEnum.PAY_SHEET_TYPE.getAttr(), new JSONObject());
            PaySheetTypeEnum paySheetTypeEnum = PaySheetTypeEnum.getByCode(paySheetTypeObj.getString("value"));
            JSONArray amountDetail = dataList.getJSONArray(PaasConstant.AMOUNTDETAIL);
            //金额中处理回款单类型从数组格式修正为数字形式
            if (amountDetail != null ) {
                amountDetail.forEach(e -> {
                    JSONObject jsonObject = (JSONObject) e;
                    if(jsonObject.get(PaySheetEnum.PAY_SHEET_TYPE.getAttr()) instanceof JSONObject){
                        JSONObject sonTypeObj = jsonObject.getJSONObject(PaySheetEnum.PAY_SHEET_TYPE.getAttr());
                        if(sonTypeObj != null && sonTypeObj.getString("value") != null){
                            jsonObject.put(PaySheetEnum.PAY_SHEET_TYPE.getAttr(), sonTypeObj.getString("value"));
                        }
                    }
                });
            }
            if (Objects.equals(paySheetTypeEnum, PaySheetTypeEnum.WRITE_OFF_PAY)) {
                dataList.put(PaySheetEnum.PAY_SHEET_TYPE.getAttr(), PaySheetTypeEnum.RED_WRITE_OFF_PAY.getCode());
                formDataAddDTO.setBusinessType(XbbRefTypeEnum.RED_WRITE_OFF_PAY.getCode());
                formDataAddDTO.setSubBusinessType(XbbRefTypeEnum.RED_WRITE_OFF_PAY.getCode());
            } else if (Objects.equals(paySheetTypeEnum, PaySheetTypeEnum.WRITE_OFF_PREPAY)) {
                dataList.put(PaySheetEnum.PAY_SHEET_TYPE.getAttr(), PaySheetTypeEnum.RED_WRITE_OFF_PREPAY.getCode());
                formDataAddDTO.setBusinessType(XbbRefTypeEnum.RED_WRITE_OFF_PREPAY.getCode());
                formDataAddDTO.setSubBusinessType(XbbRefTypeEnum.RED_WRITE_OFF_PREPAY.getCode());
            } else {
                throw new XbbException(BusinessTypeErrorCodeEnum.API_ERROR_361001);
            }
            formDataAddDTO.setDataList(dataList);
            formDataAddDTO.setSaasMark(SaasMarkEnum.SAAS.getCode());
            SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo = new SaasNeedRedundantAttrPojo();
            saasNeedRedundantAttrPojo.setReturnedPurchaseId(saasFormSaveDTO.getNewPaasFormDataEntity().getId());
            formDataAddDTO.setSaasNeedRedundantAttrPoJo(saasNeedRedundantAttrPojo);
            JSONArray ownerJsonArray = payJsonObject.getJSONArray(FieldTypeEnum.OWNERID.getAlias());
            JSONArray coUserJsonArray = payJsonObject.getJSONArray(FieldTypeEnum.COUSERID.getAlias());
            List<ReturnUserAndDepartmentPojo> ownerId = new ArrayList<>();
            List<ReturnUserAndDepartmentPojo> coUserId = new ArrayList<>();
            if (Objects.nonNull(ownerJsonArray) && ownerJsonArray.size() > BasicConstant.ZERO) {
                ownerId = JSONArray.parseArray(ownerJsonArray.toJSONString(), ReturnUserAndDepartmentPojo.class);
            }
            if (Objects.nonNull(coUserJsonArray) && coUserJsonArray.size() > BasicConstant.ZERO) {
                coUserId = JSONArray.parseArray(coUserJsonArray.toJSONString(), ReturnUserAndDepartmentPojo.class);
            }
            formDataAddDTO.setOwnerId(ownerId);
            formDataAddDTO.setCoUserId(coUserId);
            FormDataAddVO formDataAddVO = paasFormDataService.add(formDataAddDTO);
            if (formDataAddVO.getDataId() != null && isSetPaymentFlag) {
                redPaySheetIds.add(formDataAddVO.getDataId());
            }
        }
        return redPaySheetIds;
    }

    /**
     * 处理web端关联新建红冲付款单数据组装
     * @param payJsonObject web端返回新建付款单信息
     * @return 回款单实体
     * @author zhouwq
     * @date 2020/2/27 15:17
     */
    private PayPlanSheetEntityExt handlePaySheetWebPlatformLinkAddData(JSONObject payJsonObject){
        PayPlanSheetEntityExt payPlanSheetEntityExt = new PayPlanSheetEntityExt();
        if (payJsonObject == null) {
            return payPlanSheetEntityExt;
        }
        payPlanSheetEntityExt.setSerialNo(payJsonObject.getString(BasicConstant.SERIAL_NO));
        payPlanSheetEntityExt.setId(payJsonObject.getLong(StringConstant.SAAS_LINK_BUSINESS_ID));
        payPlanSheetEntityExt.setDataId(payJsonObject.getLong(StringConstant.DATA_ID));
        payPlanSheetEntityExt.setFormId(payJsonObject.getLong("formId"));
        payPlanSheetEntityExt.setMenuId(payJsonObject.getLong("menuId"));
        payPlanSheetEntityExt.setAppId(payJsonObject.getLong("appId"));
        payPlanSheetEntityExt.setAlone(payJsonObject.getInteger(FieldTypeEnum.SHEET_ALONE.getAlias()));
        payPlanSheetEntityExt.setUuid(payJsonObject.getString(FieldTypeEnum.SHEET_UUID.getAlias()));
        payPlanSheetEntityExt.setAddTime(payJsonObject.getLong("addTime"));
        payPlanSheetEntityExt.setUpdateTime(payJsonObject.getLong("updateTime"));
        payPlanSheetEntityExt.setOwnerId(payJsonObject.getString("ownerId"));
        payPlanSheetEntityExt.setFlowStatus(payJsonObject.getInteger("flowStatus"));
        payPlanSheetEntityExt.setDepartmentId(0L);
        payPlanSheetEntityExt.setDel(payJsonObject.getInteger("del"));
        payPlanSheetEntityExt.setCreatorId(payJsonObject.getString(StringConstant.CREATOR_ID));
        payJsonObject.remove("addTime");
        payJsonObject.remove("updateTime");
        payPlanSheetEntityExt.setData(payJsonObject);
        //删除创建人ID
        if (payJsonObject.get(StringConstant.CREATOR_ID) != null) {
            payJsonObject.remove(StringConstant.CREATOR_ID);
        }
        return payPlanSheetEntityExt;
    }

    /**
     * 删除红冲付款单时更新采购退货退款中合计退款金额
     * @param corpid 公司ID
     * @param refundList 退货退款集合
     * @param paymentSheetIdToAmount 付款单对应的付款金额
     * @throws XbbException error
     * @author zhouwq
     * @date 2019/12/20 15:53
     * @update 2020/3/17 by zcp 依照退货退款相应方法copy改造为采购退货，需伟强检查确认
     */
    private void updateRefundAmountByIds(String corpid, List<PaasFormDataEntityExt> refundList, Map<Long, Double> paymentSheetIdToAmount) throws XbbException {
        ReturnedPurchaseUpdateBatchDTO returnedPurchaseUpdateBatchDTO = new ReturnedPurchaseUpdateBatchDTO();
        returnedPurchaseUpdateBatchDTO.setCorpid(corpid);
        List<ReturnedPurchaseUpdateDTO> refundUpdateList = new ArrayList<>();
        for (PaasFormDataEntityExt paasFormDataEntityExt : refundList){
            ReturnedPurchaseUpdateDTO returnedPurchaseUpdateDTO = new ReturnedPurchaseUpdateDTO();
            returnedPurchaseUpdateDTO.setId(paasFormDataEntityExt.getId());
            JSONObject newData = new JSONObject();
            JSONObject oldData = paasFormDataEntityExt.getData();
            Double oldRefundAmount = getDoubleOrDefaultFromFormData(oldData, ReturnedPurchaseEnum.RETURNED_PURCHASE_AMOUNT.getAttr(), 0D);
            JSONArray paymentSheetIds = FastJsonHelper.getJsonArrOrDefaultFromFormData(oldData, ReturnedPurchaseEnum.PAY_SHEETS.getAttr(), new JSONArray());
            Double paymentSheetRefundAmount = 0D;
            for(Object paymentSheetObj : paymentSheetIds) {
                Long paymentSheetId = Long.valueOf(paymentSheetObj.toString());
                Double paymentAmount = paymentSheetIdToAmount.get(paymentSheetId);
                if (paymentAmount != null) {
                    paymentSheetRefundAmount = Arith.add(paymentSheetRefundAmount, paymentAmount);
                }
            }
            //红冲金额为负
            double newRefundAmount = oldRefundAmount + paymentSheetRefundAmount;
            if (newRefundAmount < 0) {
                throw new XbbException(RefundErrorCodeEnum.API_ERROR_215027);
            }
            newData.put(ReturnedPurchaseEnum.RETURNED_PURCHASE_AMOUNT.getAttr(), newRefundAmount);
            returnedPurchaseUpdateDTO.setData(newData);
            refundUpdateList.add(returnedPurchaseUpdateDTO);
        }
        returnedPurchaseUpdateBatchDTO.setReturnedPurchaseList(refundUpdateList);
        try{
            updateBatch(returnedPurchaseUpdateBatchDTO);
        } catch (XbbException e) {
            throw new XbbException(BuinessDefaultErrorCodeEnum.API_ERROR_200019);
        }
    }

    private List<Long> saveReturnedPurchaseInvoice(SaasFormSaveDTO saasFormSaveDTO, JSONArray invoiceArray) throws XbbException {
        Long now = DateTimeUtil.getInt();
        PaasFormDataEntity newPaasFormDataEntity = saasFormSaveDTO.getNewPaasFormDataEntity();
        String corpid = saasFormSaveDTO.getCorpid();
        Long returnedPurchaseId = newPaasFormDataEntity.getId();
        List<Long> invoiceIds = new ArrayList<>();
        if (Objects.isNull(invoiceArray)) {
            return invoiceIds;
        }
        //关联作废/红冲发票处理
        List<Long> cancelInvoiceIds = new ArrayList<>();
        for(Object obj : invoiceArray){
            JSONObject invoiceJsonObject = (JSONObject)obj;
            PaasFormDataEntity invoiceEntity = handleInvoiceWebPlatformLinkAddData(invoiceJsonObject);
            JSONObject invoiceData = invoiceEntity.getData();
            Integer isCancel = invoiceData.getInteger(PurchaseInvoiceEnum.IS_CANCEL.getAttr());
            Integer isRed = invoiceData.getInteger(PurchaseInvoiceEnum.IS_RED.getAttr());
            Long invoiceId = invoiceEntity.getId();
            if(Objects.equals(IsCancelEnum.IS_CANCEL.getCode(), isCancel)){
                cancelInvoiceIds.add(invoiceEntity.getId());
            }
            if(Objects.equals(IsRedEnum.RED.getCode(), isRed)){
                //关联红冲发票新建
                FormDataAddDTO formDataAddDTO = new FormDataAddDTO();
                BeanUtil.copyProperties(invoiceEntity, formDataAddDTO);
                BeanUtil.copyProperties(saasFormSaveDTO, formDataAddDTO);
                JSONObject data = invoiceEntity.getData();
                invoiceAmountDetailHandle(data);
                formDataAddDTO.setDataList(data);
                formDataAddDTO.setBusinessType(XbbRefTypeEnum.PURCHASE_INVOICE.getCode());
                formDataAddDTO.setSubBusinessType(XbbRefTypeEnum.PURCHASE_INVOICE.getCode());
                formDataAddDTO.setSaasMark(SaasMarkEnum.SAAS.getCode());
                SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo = new SaasNeedRedundantAttrPojo();
                saasNeedRedundantAttrPojo.setReturnedPurchaseId(returnedPurchaseId);
                formDataAddDTO.setSaasNeedRedundantAttrPoJo(saasNeedRedundantAttrPojo);
                FormDataAddVO formDataAddVO = paasFormDataService.add(formDataAddDTO);
                //发票如果开启流程，返回的发票为空
                invoiceId = formDataAddVO.getDataId();
            }
            if (invoiceId != null) {
                ReturnedPurchaseInvoiceEntity returnedPurchaseInvoiceEntity = new ReturnedPurchaseInvoiceEntity();
                returnedPurchaseInvoiceEntity.setReturnedPurchaseId(returnedPurchaseId);
                returnedPurchaseInvoiceEntity.setCorpid(corpid);
                returnedPurchaseInvoiceEntity.setDel(DelEnum.NORMAL.getDel());
                returnedPurchaseInvoiceEntity.setAddTime(now);
                returnedPurchaseInvoiceEntity.setUpdateTime(now);
                returnedPurchaseInvoiceEntity.setInvoiceId(invoiceId);
                returnedPurchaseInvoiceModel.save(returnedPurchaseInvoiceEntity);
                invoiceIds.add(invoiceId);
            }
        }
        // 关联作废发票
        if (!cancelInvoiceIds.isEmpty()) {
            CancelDTO cancelDTO = new CancelDTO();
            BeanUtil.copyProperties(saasFormSaveDTO, cancelDTO);
            cancelDTO.setSingle(0);
            cancelDTO.setStatus(1);
            cancelDTO.setBusinessType(XbbRefTypeEnum.PURCHASE_INVOICE.getCode());
            cancelDTO.setDataIdList(cancelInvoiceIds);
            listBatchService.cancel(cancelDTO);
        }
        return invoiceIds;
    }

    private PaasFormDataEntity handleInvoiceWebPlatformLinkAddData(JSONObject paymentJsonObject){
        PaasFormDataEntity paasFormDataEntity = new PaymentSheetEntityExt();
        paasFormDataEntity.setSerialNo(paymentJsonObject.getString(PaymentSheetEnum.SHEET_NO.getAttr()));
        paasFormDataEntity.setId(paymentJsonObject.getLong(StringConstant.SAAS_LINK_BUSINESS_ID));
        paasFormDataEntity.setDataId(paymentJsonObject.getLong(StringConstant.DATA_ID));
        paasFormDataEntity.setFormId(paymentJsonObject.getLong("formId"));
        paasFormDataEntity.setMenuId(paymentJsonObject.getLong("menuId"));
        paasFormDataEntity.setAppId(paymentJsonObject.getLong("appId"));
        paasFormDataEntity.setAddTime(paymentJsonObject.getLong("addTime"));
        paasFormDataEntity.setUpdateTime(paymentJsonObject.getLong("updateTime"));
        paasFormDataEntity.setOwnerId(paymentJsonObject.getString("ownerId"));
        paasFormDataEntity.setFlowStatus(paymentJsonObject.getInteger("flowStatus"));
        paasFormDataEntity.setDepartmentId(0L);
        paasFormDataEntity.setDel(paymentJsonObject.getInteger("del"));
        paasFormDataEntity.setCreatorId(paymentJsonObject.getString("creatorId"));
        paymentJsonObject.remove("addTime");
        paymentJsonObject.remove("updateTime");
        paymentJsonObject.remove(PaymentSheetEnum.SHEET_NO.getAttr());
        paasFormDataEntity.setData(paymentJsonObject);
        return paasFormDataEntity;
    }

    private void invoiceAmountDetailHandle(JSONObject jsonObject) throws XbbException {
//        JSONArray amountDetailResult = new JSONArray();
//        JSONArray array = jsonObject.getJSONArray(PaasConstant.AMOUNTDETAIL);
//        if (!array.isEmpty()) {
//            for (Object object : array) {
//                //拷贝一份原发票所有内容信息
//                JSONObject amountDetailAll = (JSONObject) jsonObject.clone();
//                //金额明细
//                JSONObject relationObj = (JSONObject) object;
//                RelationshipGetPojo relationshipGetPojo = JSONObject.parseObject(relationObj.toJSONString(), RelationshipGetPojo.class);
//                if (relationshipGetPojo.getContractId() != null && relationshipGetPojo.getContractId() != 0L) {
//                    JSONArray contractArray = new JSONArray();
//                    JSONObject contractObject = new JSONObject();
//                    contractObject.put(StringConstant.SAAS_LINK_BUSINESS_ID, relationshipGetPojo.getContractId());
//                    contractObject.put(StringConstant.SAAS_LINK_BUSINESS_NAME, relationshipGetPojo.getContractNo());
//                    contractObject.put(ContractEnum.AMOUNT.getAttr(), relationshipGetPojo.getContractAmount());
//                    contractArray.add(contractObject);
//                    amountDetailAll.put(InvoiceEnum.CONTRACT_ID.getAttr(), contractArray);
//                }
//                if (relationshipGetPojo.getPaymentId() != null && relationshipGetPojo.getPaymentId() != 0L) {
//                    JSONArray paymentArray = new JSONArray();
//                    JSONObject paymentObject = new JSONObject();
//                    paymentObject.put(StringConstant.SAAS_LINK_BUSINESS_ID, relationshipGetPojo.getPaymentId());
//                    paymentObject.put(StringConstant.SAAS_LINK_BUSINESS_NAME, relationshipGetPojo.getPaymentNo());
//                    paymentObject.put(PaymentEnum.AMOUNT.getAttr(), relationshipGetPojo.getPaymentAmount());
//                    paymentArray.add(paymentObject);
//                    amountDetailAll.put(InvoiceEnum.PAYMENT_ID.getAttr(), paymentArray);
//                }
//                if (relationshipGetPojo.getPaymentSheetId() != null && relationshipGetPojo.getPaymentSheetId() != 0L) {
//                    JSONArray paymentSheetArray = new JSONArray();
//                    JSONObject paymentSheetObject = new JSONObject();
//                    paymentSheetObject.put(StringConstant.SAAS_LINK_BUSINESS_ID, relationshipGetPojo.getPaymentSheetId());
//                    paymentSheetObject.put(StringConstant.SAAS_LINK_BUSINESS_NAME, relationshipGetPojo.getPaymentSheetNo());
//                    paymentSheetObject.put(PaymentSheetEnum.AMOUNT.getAttr(), relationshipGetPojo.getPaymentSheetAmount());
//                    paymentSheetArray.add(paymentSheetObject);
//                    amountDetailAll.put(InvoiceEnum.PAYMENT_SHEET_ID.getAttr(), paymentSheetArray);
//                }
//                Double invoiceAmount = 0D;
//                if (relationshipGetPojo.getContractInvoiceAmount() != null) {
//                    invoiceAmount = relationshipGetPojo.getContractInvoiceAmount();
//                } else if (relationshipGetPojo.getPaymentInvoiceAmount() != null) {
//                    invoiceAmount = relationshipGetPojo.getPaymentInvoiceAmount();
//                } else if (relationshipGetPojo.getPaymentSheetInvoiceAmount() != null) {
//                    invoiceAmount = relationshipGetPojo.getPaymentSheetInvoiceAmount();
//                } else {
//                    return;
//                }
//                amountDetailAll.put(InvoiceEnum.TOTAL_MONEY.getAttr(), invoiceAmount);
//
//                amountDetailResult.add(amountDetailAll);
//            }
//        }
//        jsonObject.put(PaasConstant.AMOUNTDETAIL, amountDetailResult);
    }

    @Override
    public void formatBatchExplain(List<FieldAttrEntity> fieldAttrEntityList, String enable) {
        BatchSeqExplainHelp.getInstance().formatExplain4BatchAffectProductAttr(fieldAttrEntityList, enable, RefundEnum.PRODUCTS.getAttr());
    }

    @Override
    public void updateBatchLabelAttr(AddLabelDTO addLabelDTO, List<PaasFormDataEntityExt> addBatchList, Boolean addOrDelete) throws XbbException {
        ReturnedPurchaseUpdateBatchDTO returnedPurchaseUpdateBatchDTO = new ReturnedPurchaseUpdateBatchDTO();
        BeanUtil.copyProperties(addLabelDTO, returnedPurchaseUpdateBatchDTO);
        List<ReturnedPurchaseUpdateDTO> returnedPurchaseList = new ArrayList<>();
        addBatchList.forEach(item ->{
            ReturnedPurchaseUpdateDTO returnedPurchaseUpdateDTO = new ReturnedPurchaseUpdateDTO();
            returnedPurchaseUpdateDTO.setData(item.getData());
            returnedPurchaseUpdateDTO.setId(item.getId());
            returnedPurchaseList.add(returnedPurchaseUpdateDTO);
        });
        returnedPurchaseUpdateBatchDTO.setReturnedPurchaseList(returnedPurchaseList);
        updateBatch(returnedPurchaseUpdateBatchDTO);

    }

    @Override
    public void afterSaveForWorkflow(SaasFormSaveDTO saasFormSaveDTO, ReturnedPurchaseEntityExt newReturnedPurchaseEntityExt, AssociatedBusinessAfterSavePojo associatedBusinessAfterSavePojo) throws XbbException {
        PaasFormDataEntity paasFormDataEntity = saasFormSaveDTO.getNewPaasFormDataEntity();
        ReturnedPurchaseEntityExt returnedPurchaseEntityExt = new ReturnedPurchaseEntityExt();
        BeanUtil.copyProperties(paasFormDataEntity, returnedPurchaseEntityExt);
        // 更新退货产品
        returnPurchaseHelp.setReturnedPurchaseProducts(paasFormDataEntity);
    }

    @Override
    public void afterSaveForUpdateWorkflow(SaasFormSaveDTO saasFormSaveDTO, ReturnedPurchaseEntityExt newReturnedPurchaseEntityExt, AssociatedBusinessAfterSavePojo associatedBusinessAfterSavePojo) throws XbbException {
        PaasFormDataEntity paasFormDataEntity = saasFormSaveDTO.getNewPaasFormDataEntity();
        Boolean productCanSee = saasFormSaveDTO.getSaasNeedRedundantAttrPoJo().getAttrCanSee(ReturnedPurchaseEnum.PRODUCTS.getAttr());
        if (productCanSee) {
            // 更新退货产品
            returnPurchaseHelp.setReturnedPurchaseProducts(paasFormDataEntity);
        }
    }

    @Override
    public void formatBatchOrSeqExplain(List<FieldAttrEntity> fieldAttrEntityList, String enable, String alias) {
        if (CompanyConfigEnum.ENABLE_BATCH_SHELF_MANAGEMENT.getAlias().equals(alias)) {
            formatBatchExplain(fieldAttrEntityList, enable);
        }
    }
}

